From 157cb321b06bf540592f3946708a01e557f4e7ed Mon Sep 17 00:00:00 2001 From: Santiago Medina Rolong Date: Mon, 1 Dec 2025 10:51:14 -0500 Subject: [PATCH 1/2] chore: clean up and refactor repository organization --- Batch-Compliance/java/README.md | 64 --- Batch-Compliance/java/pom.xml | 33 -- .../java/src/main/java/CreateJob.java | 61 --- .../java/src/main/java/DownloadResult.java | 49 -- .../java/src/main/java/GetJobById.java | 59 --- .../java/src/main/java/GetJobs.java | 65 --- .../java/src/main/java/UploadDataset.java | 56 -- Batch-Compliance/js/README.md | 69 --- Batch-Compliance/js/create_compliance_job.js | 47 -- .../js/download_compliance_results.js | 31 -- .../get_compliance_job_information_by_id.js | 43 -- .../js/get_list_of_compliance_jobs.js | 45 -- Batch-Compliance/js/upload_ids.js | 40 -- Batch-Compliance/python/README.md | 64 --- .../python/create_compliance_job.py | 40 -- .../python/download_compliance_results.py | 23 - .../get_compliance_job_information_by_id.py | 39 -- .../python/get_list_of_compliance_jobs.py | 39 -- Batch-Compliance/python/upload_ids.py | 26 - Blocks-Lookup/lookup_blocks.rb | 81 --- Bookmarks-lookup/bookmarks-lookup-js-sdk.js | 92 ---- Bookmarks-lookup/bookmarks_lookup.py | 103 ---- Bookmarks-lookup/bookmarks_lookup.rb | 110 ---- .../get_events_by_conversation.py | 107 ---- .../get_one_to_one_conversation_events.py | 108 ---- .../get_user_conversation_events.py | 102 ---- Filtered-Stream/FilteredStreamDemo.java | 183 ------- Filtered-Stream/filtered_stream.js | 160 ------ Filtered-Stream/filtered_stream.rb | 144 ------ Follows-Lookup/FollowersLookupDemo.java | 64 --- Follows-Lookup/FollowingLookupDemo.java | 64 --- Follows-Lookup/followers-lookup.rb | 40 -- Follows-Lookup/followers_lookup.js | 67 --- Follows-Lookup/following-lookup.rb | 40 -- Follows-Lookup/following_lookup.js | 67 --- .../FullArchiveSearchDemo.java | 65 --- Full-Archive-Search/full-archive-search.js | 51 -- Full-Archive-Search/full-archive-search.py | 40 -- Full-Archive-Search/full-archive-search.r | 26 - Full-Archive-Search/full-archive-search.rb | 49 -- .../FullArchiveTweetCountsDemo.java | 67 --- .../full_archive_tweet_counts.js | 51 -- .../full_archive_tweet_counts.py | 39 -- .../full_archive_tweet_counts.r | 25 - .../full_archive_tweet_counts.rb | 42 -- Likes-Lookup/liked_tweets.js | 46 -- Likes-Lookup/liked_tweets.py | 58 --- Likes-Lookup/liked_tweets.rb | 45 -- Likes-Lookup/liking_users.js | 49 -- Likes-Lookup/liking_users.py | 54 -- Likes-Lookup/liking_users.rb | 43 -- List-lookup/List-Tweets-lookup/List-Tweets.py | 55 -- List-lookup/List-Tweets-lookup/List-Tweets.rb | 44 -- List-lookup/List-Tweets-lookup/List-tweets.js | 47 -- .../list-followers-lookup.js | 47 -- .../list-followers-lookup.py | 51 -- .../list-followers-lookup.rb | 41 -- .../List-follows-lookup/user-list-followed.js | 48 -- .../List-follows-lookup/user-list-followed.py | 50 -- .../List-follows-lookup/user-list-followed.rb | 40 -- .../List-members-lookup/list-member-lookup.js | 47 -- .../List-members-lookup/list-member-lookup.py | 50 -- .../List-members-lookup/list-member-lookup.rb | 41 -- .../user-list-memberships.js | 47 -- .../user-list-memberships.py | 50 -- .../user-list-memberships.rb | 40 -- .../Pinned-Lists-lookup/Pinned-List.js | 150 ------ .../Pinned-Lists-lookup/Pinned-List.rb | 89 ---- List-lookup/list-lookup-by-id.js | 47 -- List-lookup/list-lookup-by-id.py | 50 -- List-lookup/list-lookup-by-id.rb | 40 -- List-lookup/user-owned-list-lookup.js | 47 -- List-lookup/user-owned-list-lookup.py | 50 -- List-lookup/user-owned-list-lookup.rb | 40 -- Manage-Blocks/block_a_user.js | 150 ------ Manage-Blocks/block_a_user.rb | 86 --- Manage-Blocks/unblock_a_user.js | 149 ------ Manage-Blocks/unblock_a_user.py | 81 --- Manage-Blocks/unblock_a_user.rb | 86 --- Manage-Bookmarks/create-bookmark-js-sdk.js | 93 ---- Manage-Bookmarks/create_bookmark.py | 107 ---- Manage-Bookmarks/create_bookmark.rb | 113 ---- Manage-Bookmarks/delete-bookmark-js-sdk.js | 91 ---- Manage-Bookmarks/delete_bookmark.py | 109 ---- Manage-Bookmarks/delete_bookmark.rb | 111 ---- .../post_dm_to_conversation.py | 113 ---- .../post_group_conversation_dm.py | 116 ----- Manage-Direct-Messages/post_one_to_one_dm.py | 114 ---- Manage-Likes/like_a_tweet.js | 148 ------ Manage-Likes/like_a_tweet.py | 77 --- Manage-Likes/like_a_tweet.rb | 86 --- Manage-Likes/unlike_a_tweet.js | 145 ------ Manage-Likes/unlike_a_tweet.py | 77 --- Manage-Likes/unlike_a_tweet.rb | 84 --- .../Manage-Followed-Lists/follow_list.js | 152 ------ .../Manage-Followed-Lists/follow_list.rb | 85 --- .../Manage-Followed-Lists/unfollow_list.js | 149 ------ .../Manage-Followed-Lists/unfollow_list.rb | 81 --- .../Manage-List-Members/add_member.js | 151 ------ .../Manage-List-Members/add_member.rb | 84 --- .../Manage-List-Members/remove_member.js | 149 ------ .../Manage-List-Members/remove_member.rb | 83 --- Manage-Lists/Manage-Pinned-Lists/pin_list.js | 152 ------ Manage-Lists/Manage-Pinned-Lists/pin_list.py | 77 --- Manage-Lists/Manage-Pinned-Lists/pin_list.rb | 85 --- .../Manage-Pinned-Lists/unpin_list.js | 149 ------ .../Manage-Pinned-Lists/unpin_list.rb | 81 --- Manage-Lists/create_a_list.js | 150 ------ Manage-Lists/create_a_list.rb | 86 --- Manage-Lists/delete_a_list.js | 144 ------ Manage-Lists/delete_a_list.rb | 83 --- Manage-Lists/update_a_list.js | 153 ------ Manage-Lists/update_a_list.rb | 89 ---- Manage-Mutes/mute_a_user.js | 150 ------ Manage-Mutes/mute_a_user.rb | 85 --- Manage-Mutes/unmute_a_user.js | 145 ------ Manage-Mutes/unmute_a_user.py | 79 --- Manage-Mutes/unmute_a_user.rb | 82 --- Manage-Retweets/.#bearer_test.py | 1 - Manage-Retweets/retweet_a_tweet.js | 148 ------ Manage-Retweets/retweet_a_tweet.py | 78 --- Manage-Retweets/retweet_a_tweet.rb | 86 --- Manage-Retweets/undo_a_retweet.js | 145 ------ Manage-Retweets/undo_a_retweet.py | 79 --- Manage-Retweets/undo_a_retweet.rb | 84 --- Manage-Tweets/create_tweet.rb | 82 --- Manage-Tweets/delete_tweet.js | 142 ----- Manage-Tweets/delete_tweet.rb | 79 --- Media Upload/media_upload_v2.py | 229 -------- Mutes-Lookup/lookup_mutes.js | 142 ----- Mutes-Lookup/lookup_mutes.py | 79 --- Mutes-Lookup/lookup_mutes.rb | 81 --- Quote-Tweets/QuoteTweetsDemo.java | 64 --- Quote-Tweets/quote_tweets.js | 74 --- Quote-Tweets/quote_tweets.py | 58 --- Quote-Tweets/quote_tweets.rb | 44 -- README.md | 160 +++--- Recent-Search/RecentSearchDemo.java | 65 --- Recent-Search/recent-search.r | 28 - Recent-Search/recent_search.js | 51 -- Recent-Search/recent_search.rb | 49 -- .../RecentTweetCountsDemo.java | 66 --- Recent-Tweet-Counts/recent_tweet_counts.js | 50 -- Recent-Tweet-Counts/recent_tweet_counts.py | 39 -- Recent-Tweet-Counts/recent_tweet_counts.r | 25 - Recent-Tweet-Counts/recent_tweet_counts.rb | 41 -- Retweets-Lookup/retweeted_by.js | 49 -- Retweets-Lookup/retweeted_by.py | 56 -- Retweets-Lookup/retweeted_by.rb | 43 -- .../reverse-chron-home-timeline.js | 142 ----- .../reverse-chron-home-timeline.py | 71 --- .../reverse-chron-home-timeline.rb | 80 --- .../reverse-chron-home-timeline-java-sdk.java | 130 ----- .../reverse-chron-home-timeline-js-sdk.js | 92 ---- .../reverse-chron-home-timeline.py | 112 ---- .../reverse-chron-home-timeline.rb | 110 ---- Sampled-Stream/SampledStream.java | 60 --- Sampled-Stream/sampled_stream.js | 60 --- Sampled-Stream/sampled_stream.rb | 51 -- Search-Spaces/SearchSpacesDemo.java | 66 --- Search-Spaces/search_spaces.js | 51 -- Search-Spaces/search_spaces.py | 40 -- Search-Spaces/search_spaces.rb | 42 -- Spaces-Lookup/SpacesLookupDemo.java | 66 --- Spaces-Lookup/spaces_lookup.js | 50 -- Spaces-Lookup/spaces_lookup.py | 38 -- Spaces-Lookup/spaces_lookup.rb | 42 -- Tweet-Lookup/TweetsDemo.java | 65 --- Tweet-Lookup/get_tweets_with_bearer_token.js | 53 -- Tweet-Lookup/get_tweets_with_bearer_token.py | 55 -- Tweet-Lookup/get_tweets_with_bearer_token.r | 21 - Tweet-Lookup/get_tweets_with_bearer_token.rb | 45 -- Tweet-Lookup/get_tweets_with_user_context.js | 150 ------ Tweet-Lookup/get_tweets_with_user_context.py | 77 --- Tweet-Lookup/get_tweets_with_user_context.rb | 91 ---- Usage Tweets/UsageTweetsDemo.java | 58 --- Usage Tweets/get_usage_tweets.js | 44 -- Usage Tweets/get_usage_tweets.py | 38 -- Usage Tweets/get_usage_tweets.rb | 29 -- User-Lookup/UsersDemo.java | 66 --- User-Lookup/get_users_me_with_user_context.js | 146 ------ User-Lookup/get_users_me_with_user_context.rb | 80 --- User-Lookup/get_users_with_bearer_token.js | 53 -- User-Lookup/get_users_with_bearer_token.r | 20 - User-Lookup/get_users_with_bearer_token.rb | 44 -- User-Lookup/get_users_with_user_context.js | 150 ------ User-Lookup/get_users_with_user_context.rb | 88 ---- User-Mention-Timeline/UserMentionsDemo.java | 64 --- User-Mention-Timeline/user-mentions.rb | 49 -- User-Mention-Timeline/user_mentions.js | 74 --- User-Tweet-Timeline/UserTweetsDemo.java | 64 --- User-Tweet-Timeline/user-tweets.rb | 55 -- User-Tweet-Timeline/user_tweets.js | 79 --- User-Tweet-Timeline/user_tweets.py | 57 -- api-index.json | 489 ++++++++++++++++++ java/README.md | 64 +++ java/posts/SearchRecent.java | 64 +++ java/users/Lookup.java | 64 +++ javascript/README.md | 78 +++ javascript/lists/lookup.js | 47 ++ .../posts/create_post.js | 54 +- .../posts/delete_post.js | 66 +-- javascript/posts/lookup.js | 47 ++ javascript/posts/search_recent.js | 49 ++ javascript/spaces/lookup.js | 45 ++ javascript/streams/filtered_stream.js | 130 +++++ javascript/timelines/user_posts.js | 48 ++ javascript/users/followers.js | 48 ++ javascript/users/lookup.js | 46 ++ llms.txt | 156 ++++++ python/README.md | 139 +++++ python/bookmarks/create.py | 54 ++ python/bookmarks/delete.py | 54 ++ python/bookmarks/lookup.py | 55 ++ python/compliance/create_job.py | 56 ++ python/compliance/get_jobs.py | 52 ++ .../direct_messages/lookup.py | 35 +- python/direct_messages/send.py | 82 +++ python/lists/create.py | 80 +++ .../lists/delete.py | 31 +- python/lists/lookup.py | 55 ++ .../media/upload.py | 56 +- python/posts/counts_full_archive.py | 52 ++ python/posts/counts_recent.py | 52 ++ .../posts/create_post.py | 25 +- .../posts/delete_post.py | 30 +- .../add_member.py => python/posts/like.py | 32 +- python/posts/liked_posts.py | 53 ++ python/posts/liking_users.py | 53 ++ python/posts/lookup.py | 61 +++ python/posts/quote_posts.py | 54 ++ .../block_a_user.py => python/posts/repost.py | 32 +- python/posts/reposted_by.py | 53 ++ python/posts/search_full_archive.py | 53 ++ .../posts/search_recent.py | 27 +- .../posts/undo_repost.py | 33 +- .../posts/unlike.py | 33 +- python/requirements.txt | 10 + python/spaces/lookup.py | 55 ++ python/spaces/search.py | 55 ++ .../streams}/filtered_stream.py | 29 +- .../streams/sampled_stream.py | 41 +- .../timelines/home_timeline.py | 39 +- .../timelines}/user_mentions.py | 33 +- python/timelines/user_posts.py | 57 ++ python/usage/get_usage.py | 53 ++ .../mute_a_user.py => python/users/block.py | 32 +- .../users/blocked.py | 41 +- .../users/followers.py | 25 +- .../users/following.py | 25 +- .../users/lookup.py | 27 +- .../users/me.py | 31 +- .../create_a_list.py => python/users/mute.py | 33 +- .../users/muted.py | 35 +- .../unpin_list.py => python/users/unblock.py | 33 +- python/users/unmute.py | 81 +++ ruby/Gemfile | 9 + ruby/README.md | 67 +++ ruby/lists/lookup.rb | 39 ++ ruby/posts/lookup.rb | 40 ++ ruby/posts/search_recent.rb | 47 ++ ruby/timelines/user_posts.rb | 40 ++ ruby/users/followers.rb | 40 ++ ruby/users/lookup.rb | 39 ++ 264 files changed, 3641 insertions(+), 15083 deletions(-) delete mode 100644 Batch-Compliance/java/README.md delete mode 100644 Batch-Compliance/java/pom.xml delete mode 100644 Batch-Compliance/java/src/main/java/CreateJob.java delete mode 100644 Batch-Compliance/java/src/main/java/DownloadResult.java delete mode 100644 Batch-Compliance/java/src/main/java/GetJobById.java delete mode 100644 Batch-Compliance/java/src/main/java/GetJobs.java delete mode 100644 Batch-Compliance/java/src/main/java/UploadDataset.java delete mode 100644 Batch-Compliance/js/README.md delete mode 100644 Batch-Compliance/js/create_compliance_job.js delete mode 100644 Batch-Compliance/js/download_compliance_results.js delete mode 100644 Batch-Compliance/js/get_compliance_job_information_by_id.js delete mode 100644 Batch-Compliance/js/get_list_of_compliance_jobs.js delete mode 100644 Batch-Compliance/js/upload_ids.js delete mode 100644 Batch-Compliance/python/README.md delete mode 100644 Batch-Compliance/python/create_compliance_job.py delete mode 100644 Batch-Compliance/python/download_compliance_results.py delete mode 100644 Batch-Compliance/python/get_compliance_job_information_by_id.py delete mode 100644 Batch-Compliance/python/get_list_of_compliance_jobs.py delete mode 100644 Batch-Compliance/python/upload_ids.py delete mode 100644 Blocks-Lookup/lookup_blocks.rb delete mode 100644 Bookmarks-lookup/bookmarks-lookup-js-sdk.js delete mode 100644 Bookmarks-lookup/bookmarks_lookup.py delete mode 100644 Bookmarks-lookup/bookmarks_lookup.rb delete mode 100644 Direct-Messages-lookup/get_events_by_conversation.py delete mode 100644 Direct-Messages-lookup/get_one_to_one_conversation_events.py delete mode 100644 Direct-Messages-lookup/get_user_conversation_events.py delete mode 100644 Filtered-Stream/FilteredStreamDemo.java delete mode 100644 Filtered-Stream/filtered_stream.js delete mode 100644 Filtered-Stream/filtered_stream.rb delete mode 100644 Follows-Lookup/FollowersLookupDemo.java delete mode 100644 Follows-Lookup/FollowingLookupDemo.java delete mode 100644 Follows-Lookup/followers-lookup.rb delete mode 100644 Follows-Lookup/followers_lookup.js delete mode 100644 Follows-Lookup/following-lookup.rb delete mode 100644 Follows-Lookup/following_lookup.js delete mode 100644 Full-Archive-Search/FullArchiveSearchDemo.java delete mode 100644 Full-Archive-Search/full-archive-search.js delete mode 100644 Full-Archive-Search/full-archive-search.py delete mode 100644 Full-Archive-Search/full-archive-search.r delete mode 100644 Full-Archive-Search/full-archive-search.rb delete mode 100644 Full-Archive-Tweet-Counts/FullArchiveTweetCountsDemo.java delete mode 100644 Full-Archive-Tweet-Counts/full_archive_tweet_counts.js delete mode 100644 Full-Archive-Tweet-Counts/full_archive_tweet_counts.py delete mode 100644 Full-Archive-Tweet-Counts/full_archive_tweet_counts.r delete mode 100644 Full-Archive-Tweet-Counts/full_archive_tweet_counts.rb delete mode 100644 Likes-Lookup/liked_tweets.js delete mode 100644 Likes-Lookup/liked_tweets.py delete mode 100644 Likes-Lookup/liked_tweets.rb delete mode 100644 Likes-Lookup/liking_users.js delete mode 100644 Likes-Lookup/liking_users.py delete mode 100644 Likes-Lookup/liking_users.rb delete mode 100644 List-lookup/List-Tweets-lookup/List-Tweets.py delete mode 100644 List-lookup/List-Tweets-lookup/List-Tweets.rb delete mode 100644 List-lookup/List-Tweets-lookup/List-tweets.js delete mode 100644 List-lookup/List-follows-lookup/list-followers-lookup.js delete mode 100644 List-lookup/List-follows-lookup/list-followers-lookup.py delete mode 100644 List-lookup/List-follows-lookup/list-followers-lookup.rb delete mode 100644 List-lookup/List-follows-lookup/user-list-followed.js delete mode 100644 List-lookup/List-follows-lookup/user-list-followed.py delete mode 100644 List-lookup/List-follows-lookup/user-list-followed.rb delete mode 100644 List-lookup/List-members-lookup/list-member-lookup.js delete mode 100644 List-lookup/List-members-lookup/list-member-lookup.py delete mode 100644 List-lookup/List-members-lookup/list-member-lookup.rb delete mode 100644 List-lookup/List-members-lookup/user-list-memberships.js delete mode 100644 List-lookup/List-members-lookup/user-list-memberships.py delete mode 100644 List-lookup/List-members-lookup/user-list-memberships.rb delete mode 100644 List-lookup/Pinned-Lists-lookup/Pinned-List.js delete mode 100644 List-lookup/Pinned-Lists-lookup/Pinned-List.rb delete mode 100644 List-lookup/list-lookup-by-id.js delete mode 100644 List-lookup/list-lookup-by-id.py delete mode 100644 List-lookup/list-lookup-by-id.rb delete mode 100644 List-lookup/user-owned-list-lookup.js delete mode 100644 List-lookup/user-owned-list-lookup.py delete mode 100644 List-lookup/user-owned-list-lookup.rb delete mode 100644 Manage-Blocks/block_a_user.js delete mode 100644 Manage-Blocks/block_a_user.rb delete mode 100644 Manage-Blocks/unblock_a_user.js delete mode 100644 Manage-Blocks/unblock_a_user.py delete mode 100644 Manage-Blocks/unblock_a_user.rb delete mode 100644 Manage-Bookmarks/create-bookmark-js-sdk.js delete mode 100644 Manage-Bookmarks/create_bookmark.py delete mode 100644 Manage-Bookmarks/create_bookmark.rb delete mode 100644 Manage-Bookmarks/delete-bookmark-js-sdk.js delete mode 100644 Manage-Bookmarks/delete_bookmark.py delete mode 100644 Manage-Bookmarks/delete_bookmark.rb delete mode 100644 Manage-Direct-Messages/post_dm_to_conversation.py delete mode 100644 Manage-Direct-Messages/post_group_conversation_dm.py delete mode 100644 Manage-Direct-Messages/post_one_to_one_dm.py delete mode 100644 Manage-Likes/like_a_tweet.js delete mode 100644 Manage-Likes/like_a_tweet.py delete mode 100644 Manage-Likes/like_a_tweet.rb delete mode 100644 Manage-Likes/unlike_a_tweet.js delete mode 100644 Manage-Likes/unlike_a_tweet.py delete mode 100644 Manage-Likes/unlike_a_tweet.rb delete mode 100644 Manage-Lists/Manage-Followed-Lists/follow_list.js delete mode 100644 Manage-Lists/Manage-Followed-Lists/follow_list.rb delete mode 100644 Manage-Lists/Manage-Followed-Lists/unfollow_list.js delete mode 100644 Manage-Lists/Manage-Followed-Lists/unfollow_list.rb delete mode 100644 Manage-Lists/Manage-List-Members/add_member.js delete mode 100644 Manage-Lists/Manage-List-Members/add_member.rb delete mode 100644 Manage-Lists/Manage-List-Members/remove_member.js delete mode 100644 Manage-Lists/Manage-List-Members/remove_member.rb delete mode 100644 Manage-Lists/Manage-Pinned-Lists/pin_list.js delete mode 100644 Manage-Lists/Manage-Pinned-Lists/pin_list.py delete mode 100644 Manage-Lists/Manage-Pinned-Lists/pin_list.rb delete mode 100644 Manage-Lists/Manage-Pinned-Lists/unpin_list.js delete mode 100644 Manage-Lists/Manage-Pinned-Lists/unpin_list.rb delete mode 100644 Manage-Lists/create_a_list.js delete mode 100644 Manage-Lists/create_a_list.rb delete mode 100644 Manage-Lists/delete_a_list.js delete mode 100644 Manage-Lists/delete_a_list.rb delete mode 100644 Manage-Lists/update_a_list.js delete mode 100644 Manage-Lists/update_a_list.rb delete mode 100644 Manage-Mutes/mute_a_user.js delete mode 100644 Manage-Mutes/mute_a_user.rb delete mode 100644 Manage-Mutes/unmute_a_user.js delete mode 100644 Manage-Mutes/unmute_a_user.py delete mode 100644 Manage-Mutes/unmute_a_user.rb delete mode 120000 Manage-Retweets/.#bearer_test.py delete mode 100644 Manage-Retweets/retweet_a_tweet.js delete mode 100644 Manage-Retweets/retweet_a_tweet.py delete mode 100644 Manage-Retweets/retweet_a_tweet.rb delete mode 100644 Manage-Retweets/undo_a_retweet.js delete mode 100644 Manage-Retweets/undo_a_retweet.py delete mode 100644 Manage-Retweets/undo_a_retweet.rb delete mode 100644 Manage-Tweets/create_tweet.rb delete mode 100644 Manage-Tweets/delete_tweet.js delete mode 100644 Manage-Tweets/delete_tweet.rb delete mode 100644 Media Upload/media_upload_v2.py delete mode 100644 Mutes-Lookup/lookup_mutes.js delete mode 100644 Mutes-Lookup/lookup_mutes.py delete mode 100644 Mutes-Lookup/lookup_mutes.rb delete mode 100644 Quote-Tweets/QuoteTweetsDemo.java delete mode 100644 Quote-Tweets/quote_tweets.js delete mode 100644 Quote-Tweets/quote_tweets.py delete mode 100644 Quote-Tweets/quote_tweets.rb delete mode 100644 Recent-Search/RecentSearchDemo.java delete mode 100644 Recent-Search/recent-search.r delete mode 100644 Recent-Search/recent_search.js delete mode 100644 Recent-Search/recent_search.rb delete mode 100644 Recent-Tweet-Counts/RecentTweetCountsDemo.java delete mode 100644 Recent-Tweet-Counts/recent_tweet_counts.js delete mode 100644 Recent-Tweet-Counts/recent_tweet_counts.py delete mode 100644 Recent-Tweet-Counts/recent_tweet_counts.r delete mode 100644 Recent-Tweet-Counts/recent_tweet_counts.rb delete mode 100644 Retweets-Lookup/retweeted_by.js delete mode 100644 Retweets-Lookup/retweeted_by.py delete mode 100644 Retweets-Lookup/retweeted_by.rb delete mode 100644 Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.js delete mode 100644 Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.py delete mode 100644 Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.rb delete mode 100644 Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-java-sdk.java delete mode 100644 Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-js-sdk.js delete mode 100644 Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.py delete mode 100644 Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.rb delete mode 100644 Sampled-Stream/SampledStream.java delete mode 100644 Sampled-Stream/sampled_stream.js delete mode 100644 Sampled-Stream/sampled_stream.rb delete mode 100644 Search-Spaces/SearchSpacesDemo.java delete mode 100644 Search-Spaces/search_spaces.js delete mode 100644 Search-Spaces/search_spaces.py delete mode 100644 Search-Spaces/search_spaces.rb delete mode 100644 Spaces-Lookup/SpacesLookupDemo.java delete mode 100644 Spaces-Lookup/spaces_lookup.js delete mode 100644 Spaces-Lookup/spaces_lookup.py delete mode 100644 Spaces-Lookup/spaces_lookup.rb delete mode 100644 Tweet-Lookup/TweetsDemo.java delete mode 100644 Tweet-Lookup/get_tweets_with_bearer_token.js delete mode 100644 Tweet-Lookup/get_tweets_with_bearer_token.py delete mode 100644 Tweet-Lookup/get_tweets_with_bearer_token.r delete mode 100644 Tweet-Lookup/get_tweets_with_bearer_token.rb delete mode 100644 Tweet-Lookup/get_tweets_with_user_context.js delete mode 100644 Tweet-Lookup/get_tweets_with_user_context.py delete mode 100644 Tweet-Lookup/get_tweets_with_user_context.rb delete mode 100644 Usage Tweets/UsageTweetsDemo.java delete mode 100644 Usage Tweets/get_usage_tweets.js delete mode 100644 Usage Tweets/get_usage_tweets.py delete mode 100644 Usage Tweets/get_usage_tweets.rb delete mode 100644 User-Lookup/UsersDemo.java delete mode 100644 User-Lookup/get_users_me_with_user_context.js delete mode 100644 User-Lookup/get_users_me_with_user_context.rb delete mode 100644 User-Lookup/get_users_with_bearer_token.js delete mode 100644 User-Lookup/get_users_with_bearer_token.r delete mode 100644 User-Lookup/get_users_with_bearer_token.rb delete mode 100644 User-Lookup/get_users_with_user_context.js delete mode 100644 User-Lookup/get_users_with_user_context.rb delete mode 100644 User-Mention-Timeline/UserMentionsDemo.java delete mode 100644 User-Mention-Timeline/user-mentions.rb delete mode 100644 User-Mention-Timeline/user_mentions.js delete mode 100644 User-Tweet-Timeline/UserTweetsDemo.java delete mode 100644 User-Tweet-Timeline/user-tweets.rb delete mode 100644 User-Tweet-Timeline/user_tweets.js delete mode 100644 User-Tweet-Timeline/user_tweets.py create mode 100644 api-index.json create mode 100644 java/README.md create mode 100644 java/posts/SearchRecent.java create mode 100644 java/users/Lookup.java create mode 100644 javascript/README.md create mode 100644 javascript/lists/lookup.js rename Manage-Tweets/create_tweet.js => javascript/posts/create_post.js (67%) rename Blocks-Lookup/lookup_blocks.js => javascript/posts/delete_post.js (60%) create mode 100644 javascript/posts/lookup.js create mode 100644 javascript/posts/search_recent.js create mode 100644 javascript/spaces/lookup.js create mode 100644 javascript/streams/filtered_stream.js create mode 100644 javascript/timelines/user_posts.js create mode 100644 javascript/users/followers.js create mode 100644 javascript/users/lookup.js create mode 100644 llms.txt create mode 100644 python/README.md create mode 100644 python/bookmarks/create.py create mode 100644 python/bookmarks/delete.py create mode 100644 python/bookmarks/lookup.py create mode 100644 python/compliance/create_job.py create mode 100644 python/compliance/get_jobs.py rename Manage-Lists/Manage-Followed-Lists/follow_list.py => python/direct_messages/lookup.py (67%) create mode 100644 python/direct_messages/send.py create mode 100644 python/lists/create.py rename Manage-Lists/delete_a_list.py => python/lists/delete.py (73%) create mode 100644 python/lists/lookup.py rename Manage-Lists/update_a_list.py => python/media/upload.py (57%) create mode 100644 python/posts/counts_full_archive.py create mode 100644 python/posts/counts_recent.py rename Manage-Tweets/create_tweet.py => python/posts/create_post.py (72%) rename Manage-Tweets/delete_tweet.py => python/posts/delete_post.py (71%) rename Manage-Lists/Manage-List-Members/add_member.py => python/posts/like.py (71%) create mode 100644 python/posts/liked_posts.py create mode 100644 python/posts/liking_users.py create mode 100644 python/posts/lookup.py create mode 100644 python/posts/quote_posts.py rename Manage-Blocks/block_a_user.py => python/posts/repost.py (69%) create mode 100644 python/posts/reposted_by.py create mode 100644 python/posts/search_full_archive.py rename Recent-Search/recent_search.py => python/posts/search_recent.py (54%) rename Manage-Lists/Manage-Followed-Lists/unfollow_list.py => python/posts/undo_repost.py (69%) rename Manage-Lists/Manage-List-Members/remove_member.py => python/posts/unlike.py (70%) create mode 100644 python/requirements.txt create mode 100644 python/spaces/lookup.py create mode 100644 python/spaces/search.py rename {Filtered-Stream => python/streams}/filtered_stream.py (75%) rename Sampled-Stream/sampled-stream.py => python/streams/sampled_stream.py (55%) rename List-lookup/Pinned-Lists-lookup/Pinned-List.py => python/timelines/home_timeline.py (63%) rename {User-Mention-Timeline => python/timelines}/user_mentions.py (51%) create mode 100644 python/timelines/user_posts.py create mode 100644 python/usage/get_usage.py rename Manage-Mutes/mute_a_user.py => python/users/block.py (70%) rename Blocks-Lookup/lookup_blocks.py => python/users/blocked.py (66%) rename Follows-Lookup/followers_lookup.py => python/users/followers.py (60%) rename Follows-Lookup/following_lookup.py => python/users/following.py (60%) rename User-Lookup/get_users_with_bearer_token.py => python/users/lookup.py (63%) rename User-Lookup/get_users_me_user_context.py => python/users/me.py (71%) rename Manage-Lists/create_a_list.py => python/users/mute.py (70%) rename User-Lookup/get_users_with_user_context.py => python/users/muted.py (70%) rename Manage-Lists/Manage-Pinned-Lists/unpin_list.py => python/users/unblock.py (70%) create mode 100644 python/users/unmute.py create mode 100644 ruby/Gemfile create mode 100644 ruby/README.md create mode 100644 ruby/lists/lookup.rb create mode 100644 ruby/posts/lookup.rb create mode 100644 ruby/posts/search_recent.rb create mode 100644 ruby/timelines/user_posts.rb create mode 100644 ruby/users/followers.rb create mode 100644 ruby/users/lookup.rb diff --git a/Batch-Compliance/java/README.md b/Batch-Compliance/java/README.md deleted file mode 100644 index b702cfe..0000000 --- a/Batch-Compliance/java/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Batch Compliance sample code - -This folder contains scripts to connect to the [Batch compliance endpoints](https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/introduction) in Python. Make sure you have your BEARER_TOKEN set up as an environment variable. Also, make sure you have the appropriate dependencies installed by running `mvn install` in the folder that you have the pom.xml in. Then, run the scripts in the following order: - -## 1. Create compliance job - -First, run the `CreateJob` file. In this file, make sure to specify your `type` as `tweets` or `users`, based on whether you will uploading a dataset with Tweet IDs or User IDs. This will give you a response like: - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T15:24:31.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "created", - "name": "my_job", - "upload_expires_at": "2021-08-05T15:39:31.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T15:24:31.000Z", - "type": "tweets" - } -} -``` - -Note the `id` from here as well as well as the upload_url, as this is the URL you will upload the file with Tweet IDs or User IDs to. - -## 2. Upload the Tweet IDs or User IDs to check for compliance - -Next, you will upload the file with Tweet IDs or User IDs to check for compliance. To do this, you will run the `UploadDataset` file. Make sure to replace the `uploadUrl` with your `upload_url` from the previous step and make sure to specify the path to your text file that contains the Tweet IDs or User IDs, one ID per line. - -## 3. Check the status of your compliance job - -Now that you have uploaded your dataset to check for compliance, your status will be in_progress. You can download the result of your compliance job, once the `status` is complete. To check for the status of your job, there are two options: - -### Get all jobs - -In order to get all your jobs, you can run `GetJobs`. Make sure to specify the appropriate job_type in this file i.e. tweets or users - -### Get job by job ID - -You can also get the job information for a job using the `id` from obtained in step 1. Run `GetJobById` and make sure to replace the jobId with your job id obtained in step 1. This will give you your job status and the `download_url`. - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T02:34:13.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "expired", - "upload_expires_at": "2021-08-05T02:49:13.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T02:34:13.000Z", - "type": "tweets" - } -} -``` - -Once your `status` changes from `in_progress` to `complete`, note the `download_url` and go to the next step to download your results - -## 4. Download your results - -In order to download your results, you will need the `download_url` from the previous step (once the job status is complete). Run the `DownloadResult` file and make sure to replace the `downloadUrl` value with your appropriate value obtained from the previous step. \ No newline at end of file diff --git a/Batch-Compliance/java/pom.xml b/Batch-Compliance/java/pom.xml deleted file mode 100644 index 9f16248..0000000 --- a/Batch-Compliance/java/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - 4.0.0 - - org.example - batch-compliance - 1.0-SNAPSHOT - - - org.apache.httpcomponents - httpcore - 4.4.11 - - - org.apache.httpcomponents - httpclient - 4.5.13 - - - org.apache.httpcomponents - httpmime - 4.5.2 - - - - - 8 - 8 - - - \ No newline at end of file diff --git a/Batch-Compliance/java/src/main/java/CreateJob.java b/Batch-Compliance/java/src/main/java/CreateJob.java deleted file mode 100644 index e9d7b8d..0000000 --- a/Batch-Compliance/java/src/main/java/CreateJob.java +++ /dev/null @@ -1,61 +0,0 @@ -import java.io.IOException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ByteArrayEntity; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to create a batch compliance job - * */ -public class CreateJob { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Specify if you want to create a job for tweets or users - String response = createJob("tweets", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the batch compliance endpoint to create a new job - * */ - private static String createJob(String type, String bearerToken) throws IOException { - String jobResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - HttpPost httpPost = new HttpPost("https://api.twitter.com/2/compliance/jobs"); - httpPost.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpPost.setHeader("Content-Type", "application/json"); - - String body = String.format("{\n" + - " \"type\": \"%s\"\n" + - "}", type); - HttpEntity requestEntity = new ByteArrayEntity(body.getBytes("UTF-8")); - httpPost.setEntity(requestEntity); - - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - if (null != entity) { - jobResponse = EntityUtils.toString(entity, "UTF-8"); - } - return jobResponse; - } - -} \ No newline at end of file diff --git a/Batch-Compliance/java/src/main/java/DownloadResult.java b/Batch-Compliance/java/src/main/java/DownloadResult.java deleted file mode 100644 index 3b4cf94..0000000 --- a/Batch-Compliance/java/src/main/java/DownloadResult.java +++ /dev/null @@ -1,49 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to download batch compliance result - * */ -public class DownloadResult { - - public static void main(String args[]) throws IOException, URISyntaxException { - // Replace with your job downloadUrl below - String downloadUrl = ""; - String response = getResults(downloadUrl); - System.out.println(response); - } - - /* - * This method gets the results for a batch compliance job - * */ - private static String getResults(String downloadUrl) throws IOException, URISyntaxException { - String jobResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(downloadUrl); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - jobResponse = EntityUtils.toString(entity, "UTF-8"); - } - return jobResponse; - } - -} \ No newline at end of file diff --git a/Batch-Compliance/java/src/main/java/GetJobById.java b/Batch-Compliance/java/src/main/java/GetJobById.java deleted file mode 100644 index ce8f131..0000000 --- a/Batch-Compliance/java/src/main/java/GetJobById.java +++ /dev/null @@ -1,59 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to get batch compliance job by ID - * */ -public class GetJobById { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - // Specify your job ID below - String jobId = ""; - String response = getJobById(jobId, bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the batch compliance endpoint to get job by id - * */ - private static String getJobById(String id, String bearerToken) throws IOException, URISyntaxException { - String jobResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/compliance/jobs/" + id); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - jobResponse = EntityUtils.toString(entity, "UTF-8"); - } - return jobResponse; - } - -} \ No newline at end of file diff --git a/Batch-Compliance/java/src/main/java/GetJobs.java b/Batch-Compliance/java/src/main/java/GetJobs.java deleted file mode 100644 index 1b5b9ad..0000000 --- a/Batch-Compliance/java/src/main/java/GetJobs.java +++ /dev/null @@ -1,65 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to get all batch compliance jobs - * */ -public class GetJobs { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - // Specify if you want to jobs for tweets or users - String response = getJobs("tweets", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the batch compliance endpoint to get all jobs - * */ - private static String getJobs(String type, String bearerToken) throws IOException, URISyntaxException { - String jobResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/compliance/jobs"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("type", type)); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - jobResponse = EntityUtils.toString(entity, "UTF-8"); - } - return jobResponse; - } - -} \ No newline at end of file diff --git a/Batch-Compliance/java/src/main/java/UploadDataset.java b/Batch-Compliance/java/src/main/java/UploadDataset.java deleted file mode 100644 index a9aae85..0000000 --- a/Batch-Compliance/java/src/main/java/UploadDataset.java +++ /dev/null @@ -1,56 +0,0 @@ -import java.io.File; -import java.io.IOException; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.entity.mime.MultipartEntityBuilder; -import org.apache.http.entity.mime.content.FileBody; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to upload a dataset for compliance - * */ -public class UploadDataset { - - public static void main(String args[]) throws IOException { - // Replace with your path to the file that contains the Tweet or User Ids - String path = ""; - // Replace the upload url with the appropriate url - String uploadUrl = ""; - String response = uploadDataset(uploadUrl, path); - System.out.println(response); - } - - /* - * This method uploads a list of Tweet or User Ids to the upload_url - * */ - private static String uploadDataset(String uploadUrl, String path) throws IOException { - File file = new File(path); - - String jobResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - HttpPut httpPut = new HttpPut(uploadUrl); - httpPut.setHeader("Content-Type", "text/plain"); - - HttpEntity body = MultipartEntityBuilder.create().addPart("file", new FileBody(file)).build(); - httpPut.setEntity(body); - - HttpResponse response = httpClient.execute(httpPut); - HttpEntity entity = response.getEntity(); - if (null != entity) { - jobResponse = EntityUtils.toString(entity, "UTF-8"); - } - return jobResponse; - } - -} \ No newline at end of file diff --git a/Batch-Compliance/js/README.md b/Batch-Compliance/js/README.md deleted file mode 100644 index ab63abf..0000000 --- a/Batch-Compliance/js/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# Batch Compliance sample code - -This folder contains scripts to connect to the [Batch compliance endpoints](https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/introduction) in Node.JS. - -- Make sure you have your BEARER_TOKEN set up as an environment variable. -- Make sure you have `needle` installed by running `npm install needle` - -Run the scripts in the following order: - -## 1. Create compliance job - -First, run the `create_compliance_job.js` file. In this file, make sure to specify your `type` as `tweets` or `users`, based on whether you will uploading a dataset with Tweet IDs or User IDs. This will give you a response like: - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T15:24:31.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "created", - "name": "my_job", - "upload_expires_at": "2021-08-05T15:39:31.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T15:24:31.000Z", - "type": "tweets" - } -} -``` - -Note the `id` from here as well as well as the upload_url, as this is the URL you will upload the file with Tweet IDs or User IDs to. - -## 2. Upload the Tweet IDs or User IDs to check for compliance - -Next, you will upload the file with Tweet IDs or User IDs to check for compliance. To do this, you will run the `upload_ids.js` file. Make sure to replace the `uploadUrl` with your `upload_url` value from the previous step and make sure to specify the path to your text file that contains the Tweet IDs or User IDs, one ID per line. - -## 3. Check the status of your compliance job - -Now that you have uploaded your dataset to check for compliance, your status will be in_progress. You can download the result of your compliance job, once the `status` is complete. To check for the status of your job, there are two options: - -### Get all jobs - -In order to get all your jobs, you can run `get_list_of_compliance_jobs.js`. Make sure to specify the appropriate type in this file i.e. tweets or users - -### Get job by job ID - -You can also get the job information for a job using the `id` from obtained in step 1. Run `get_compliance_job_information_by_id.js` and make sure to replace the id with your job id obtained in step 1. This will give you the status and the `download_url`. - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T02:34:13.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "expired", - "upload_expires_at": "2021-08-05T02:49:13.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T02:34:13.000Z", - "type": "tweets" - } -} -``` - -Once your `status` changes from `in_progress` to `complete`, note the `download_url` and go to the next step to download your results - -## 4. Download your results - -In order to download your results, you will need the `download_url` from the previous step (once the status is complete). Run the `download_compliance_results.js` file and make sure to replace the `downloadUrl` value in the code with your appropriate value obtained from the previous step. diff --git a/Batch-Compliance/js/create_compliance_job.js b/Batch-Compliance/js/create_compliance_job.js deleted file mode 100644 index 4d8c170..0000000 --- a/Batch-Compliance/js/create_compliance_job.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = 'https://api.twitter.com/2/compliance/jobs' - -// For User Compliance Job, replace type value with users instead of tweets -// Also replace the name value with your desired job name -const data = { - "type": "tweets", - "name": 'my_batch_compliance_job' -} - -async function makeRequest() { - - const res = await needle.post(endpointUrl, { - json: data, - headers: { - "User-Agent": "v2BatchComplianceJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - try { - // Make request - const response = await makeRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Batch-Compliance/js/download_compliance_results.js b/Batch-Compliance/js/download_compliance_results.js deleted file mode 100644 index f23a960..0000000 --- a/Batch-Compliance/js/download_compliance_results.js +++ /dev/null @@ -1,31 +0,0 @@ -const needle = require('needle'); - -// Replace with your job download_url -downloadUrl = '' - -async function getRequest() { - - const res = await needle('get', downloadUrl, { compressed: true }) - - if (res.body) { - return res.body.toString('utf8'); - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Batch-Compliance/js/get_compliance_job_information_by_id.js b/Batch-Compliance/js/get_compliance_job_information_by_id.js deleted file mode 100644 index 93bbd29..0000000 --- a/Batch-Compliance/js/get_compliance_job_information_by_id.js +++ /dev/null @@ -1,43 +0,0 @@ -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -// Replace with your job ID -jobId = '' - -const endpointUrl = `https://api.twitter.com/2/compliance/jobs/${jobId}` - -async function getRequest() { - - const res = await needle('get', endpointUrl, { - headers: { - "User-Agent": "v2BatchComplianceJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Batch-Compliance/js/get_list_of_compliance_jobs.js b/Batch-Compliance/js/get_list_of_compliance_jobs.js deleted file mode 100644 index b878559..0000000 --- a/Batch-Compliance/js/get_list_of_compliance_jobs.js +++ /dev/null @@ -1,45 +0,0 @@ -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = 'https://api.twitter.com/2/compliance/jobs' - -// For User Compliance job, replace the value for type with users -const params = { - "type": "tweets", -} - -async function getRequest() { - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2BatchComplianceJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Batch-Compliance/js/upload_ids.js b/Batch-Compliance/js/upload_ids.js deleted file mode 100644 index 73ccc5d..0000000 --- a/Batch-Compliance/js/upload_ids.js +++ /dev/null @@ -1,40 +0,0 @@ -const got = require('got'); -const fs = require('fs'); - -// Replace with your job download_url -uploadUrl = '' - -// Replace with your file path that contains the list of Tweet IDs or User IDs, one ID per line -const readStream = fs.createReadStream('/path/to/file'); - -async function getRequest() { - - const res = await got.put(uploadUrl, { - body: readStream, - headers: { - "Content-Type": "text/plain" - } - }) - - if (res.statusCode == 200) { - return res.statusCode; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Batch-Compliance/python/README.md b/Batch-Compliance/python/README.md deleted file mode 100644 index 2314228..0000000 --- a/Batch-Compliance/python/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# Batch Compliance sample code - -This folder contains scripts to connect to the [Batch compliance endpoints](https://developer.twitter.com/en/docs/twitter-api/compliance/batch-compliance/introduction) in Python. Make sure you have your BEARER_TOKEN set up as an environment variable. Run the scripts in the following order: - -## 1. Create compliance job - -First, run the `create_compliance_job.py` file. In this file, make sure to specify your `type` as `tweets` or `users`, based on whether you will uploading a dataset with Tweet IDs or User IDs. This will give you a response like: - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T15:24:31.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "created", - "name": "my_job", - "upload_expires_at": "2021-08-05T15:39:31.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T15:24:31.000Z", - "type": "tweets" - } -} -``` - -Note the `id` from here as well as well as the upload_url, as this is the URL you will upload the file with Tweet IDs or User IDs to. - -## 2. Upload the Tweet IDs or User IDs to check for compliance - -Next, you will upload the file with Tweet IDs or User IDs to check for compliance. To do this, you will run the `upload_ids.py` file. Make sure to replace the `upload_url` with your `upload_url` from the previous step and make sure to specify the path to your text file that contains the Tweet IDs or User IDs, one ID per line. - -## 3. Check the status of your compliance job - -Now that you have uploaded your dataset to check for compliance, your status will be in_progress. You can download the result of your compliance job, once the `status` is complete. To check for the status of your job, there are two options: - -### Get all jobs - -In order to get all your jobs, you can run `get_list_of_compliance_jobs.py`. Make sure to specify the appropriate type in this file i.e. tweets or users - -### Get job by job ID - -You can also get the job information for a job using the `id` from obtained in step 1. Run `get_compliance_job_information_by_id.py` and make sure to replace the id with your job id obtained in step 1. This will give you the status and the `download_url`. - -```json -{ - "data": { - "resumable": false, - "upload_url": "https://storage.googleapis.com/...", - "download_expires_at": "2021-08-12T02:34:13.000Z", - "download_url": "https://storage.googleapis.com/...", - "status": "expired", - "upload_expires_at": "2021-08-05T02:49:13.000Z", - "id": "XXXXX", - "created_at": "2021-08-05T02:34:13.000Z", - "type": "tweets" - } -} -``` - -Once your `status` changes from `in_progress` to `complete`, note the `download_url` and go to the next step to download your results - -## 4. Download your results - -In order to download your results, you will need the `download_url` from the previous step (once the status is complete). Run the `download_compliance_results.py` file and make sure to replace the `download_url` value with your appropriate value obtained from the previous step. \ No newline at end of file diff --git a/Batch-Compliance/python/create_compliance_job.py b/Batch-Compliance/python/create_compliance_job.py deleted file mode 100644 index e856c47..0000000 --- a/Batch-Compliance/python/create_compliance_job.py +++ /dev/null @@ -1,40 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -compliance_job_url = "https://api.twitter.com/2/compliance/jobs" - -# For User Compliance Job, replace the type value with users instead of tweets -# Also replace the name value with your desired job name -body = {"type": "tweets", "name": "my_batch_compliance_job"} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2BatchCompliancePython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("POST", url, auth=bearer_oauth, json=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(compliance_job_url, body) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Batch-Compliance/python/download_compliance_results.py b/Batch-Compliance/python/download_compliance_results.py deleted file mode 100644 index 7c46399..0000000 --- a/Batch-Compliance/python/download_compliance_results.py +++ /dev/null @@ -1,23 +0,0 @@ -import requests - -# Replace with your job download_url -download_url = '' - - -def connect_to_endpoint(url): - response = requests.request("GET", url) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.text - - -def main(): - response = connect_to_endpoint(download_url) - entries = response.splitlines() - for entry in entries: - print(entry) - - -if __name__ == "__main__": - main() diff --git a/Batch-Compliance/python/get_compliance_job_information_by_id.py b/Batch-Compliance/python/get_compliance_job_information_by_id.py deleted file mode 100644 index 474585a..0000000 --- a/Batch-Compliance/python/get_compliance_job_information_by_id.py +++ /dev/null @@ -1,39 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -# Replace with your job ID below -job_id = '' - -compliance_job_url = f"https://api.twitter.com/2/compliance/jobs/{job_id}".format(job_id) - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2BatchCompliancePython" - return r - - -def connect_to_endpoint(url): - response = requests.request("GET", url, auth=bearer_oauth) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(compliance_job_url) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Batch-Compliance/python/get_list_of_compliance_jobs.py b/Batch-Compliance/python/get_list_of_compliance_jobs.py deleted file mode 100644 index 1fcb80f..0000000 --- a/Batch-Compliance/python/get_list_of_compliance_jobs.py +++ /dev/null @@ -1,39 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -compliance_job_url = "https://api.twitter.com/2/compliance/jobs" - -# For User Compliance job, replace the value for type with users -query_params = {"type": "tweets"} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2BatchCompliancePython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("GET", url, auth=bearer_oauth, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(compliance_job_url, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Batch-Compliance/python/upload_ids.py b/Batch-Compliance/python/upload_ids.py deleted file mode 100644 index 4c41aba..0000000 --- a/Batch-Compliance/python/upload_ids.py +++ /dev/null @@ -1,26 +0,0 @@ -import requests - -# Replace with your job download_url -upload_url = '' - -# Replace with your file path that contains the list of Tweet IDs or User IDs, one ID per line -file_path = '' - -headers = {'Content-Type': "text/plain"} - - -def connect_to_endpoint(url): - response = requests.put(url, data=open(file_path, 'rb'), headers=headers) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.text - - -def main(): - response = connect_to_endpoint(upload_url) - print(response) - - -if __name__ == "__main__": - main() diff --git a/Blocks-Lookup/lookup_blocks.rb b/Blocks-Lookup/lookup_blocks.rb deleted file mode 100644 index 1fb62f1..0000000 --- a/Blocks-Lookup/lookup_blocks.rb +++ /dev/null @@ -1,81 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -blocking_url = "https://api.twitter.com/2/users/#{id}/blocking" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_block(url, oauth_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2BlocksLookupRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = user_block(blocking_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Bookmarks-lookup/bookmarks-lookup-js-sdk.js b/Bookmarks-lookup/bookmarks-lookup-js-sdk.js deleted file mode 100644 index b6da60c..0000000 --- a/Bookmarks-lookup/bookmarks-lookup-js-sdk.js +++ /dev/null @@ -1,92 +0,0 @@ -const { Client, auth } = require("twitter-api-sdk"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -//Helper function to parse callback -const getQueryStringParams = (query) => { - return query - ? (/^[?#]/.test(query) ? query.slice(1) : query) - .split(/[\?\&]/) - .reduce((params, param) => { - let [key, value] = param.split("="); - params[key] = value - ? decodeURIComponent(value.replace(/\+/g, " ")) - : ""; - return params; - }, {}) - : {}; -}; - -//Helper terminal input function -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CLIENT_ID='YOUR-CLIENT-ID' -// export CLIENET_SECRET='YOUR-CLIENT-SECRET' -const CLIENT_ID = process.env.CLIENT_ID; -const CLIENT_SECRET = process.env.CLIENT_SECRET; - -// Optional parameters for additional payload data -const params = { - expansions: "author_id", - "user.fields": ["username", "created_at"], - "tweet.fields": ["geo", "entities", "context_annotations"], -}; - -(async () => { - const authClient = new auth.OAuth2User({ - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - callback: "https://www.example.com/oauth", - scopes: ["tweet.read", "users.read", "bookmark.read"], - }); - - const client = new Client(authClient); - const STATE = "my-state"; - - //Get authorization - const authUrl = authClient.generateAuthURL({ - state: STATE, - code_challenge: "challenge", - }); - - console.log(`Please go here and authorize:`, authUrl); - - //Input users callback url in termnial - const redirectCallback = await input("Paste the redirected callback here: "); - - try { - //Parse callback - const { state, code } = getQueryStringParams(redirectCallback); - if (state !== STATE) { - console.log("State isn't matching"); - } - //Gets access token - await authClient.requestAccessToken(code); - - //Get the user ID - const { - data: { id }, - } = await client.users.findMyUser(); - - //Makes api call - const getBookmark = await client.bookmarks.getUsersIdBookmarks(id, params); - console.dir(getBookmark, { - depth: null, - }); - process.exit(); - } catch (error) { - console.log(error); - } -})(); diff --git a/Bookmarks-lookup/bookmarks_lookup.py b/Bookmarks-lookup/bookmarks_lookup.py deleted file mode 100644 index 4cb2dae..0000000 --- a/Bookmarks-lookup/bookmarks_lookup.py +++ /dev/null @@ -1,103 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests.auth import AuthBase, HTTPBasicAuth -from requests_oauthlib import OAuth2Session - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = os.environ.get("CLIENT_ID") - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = os.environ.get("CLIENT_SECRET") - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Set the scopes -scopes = ["bookmark.read", "tweet.read", "users.read", "offline.access"] - -# Create a code verifier -code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") -code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - -# Create a code challenge -code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() -code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") -code_challenge = code_challenge.replace("=", "") - -# Start an OAuth 2.0 session -oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - -# Create an authorize URL -auth_url = "https://twitter.com/i/oauth2/authorize" -authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" -) - -# Visit the URL to authorize your App to make requests on behalf of a user -print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" -) -print(authorization_url) - -# Paste in your authorize URL to complete the request -authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" -) - -# Fetch your access token -token_url = "https://api.twitter.com/2/oauth2/token" - -# The following line of code will only work if you are using a type of App that is a public client -auth = False - -# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. - -# Please remove the comment on the following line if you are using a type of App that is a confidential client -# auth = HTTPBasicAuth(client_id, client_secret) - -token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, -) - -# Your access token -access = token["access_token"] - -# Make a request to the users/me endpoint to get your user ID -user_me = requests.request( - "GET", - "https://api.twitter.com/2/users/me", - headers={"Authorization": "Bearer {}".format(access)}, -).json() -user_id = user_me["data"]["id"] - -# Make a request to the bookmarks url -url = "https://api.twitter.com/2/users/{}/bookmarks".format(user_id) -headers = { - "Authorization": "Bearer {}".format(access), - "User-Agent": "BookmarksSampleCode", -} -response = requests.request("GET", url, headers=headers) -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Bookmarks-lookup/bookmarks_lookup.rb b/Bookmarks-lookup/bookmarks_lookup.rb deleted file mode 100644 index 89fc4cf..0000000 --- a/Bookmarks-lookup/bookmarks_lookup.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'json' -require 'typhoeus' -require 'twitter_oauth2' - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = ENV["CLIENT_ID"] - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = ENV["CLIENT_SECRET"] - - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Start an OAuth 2.0 session with a public client -client = TwitterOAuth2::Client.new( - identifier: "#{client_id}", - redirect_uri: "#{redirect_uri}" -) - -# Start an OAuth 2.0 session with a confidential client - -# Remove the comment on the following lines if you are using a confidential client -# client = TwitterOAuth2::Client.new( -# identifier: "#{client_id}", -# secret: "#{client_secret}", -# redirect_uri: "#{redirect_uri}" -# ) - -# Create your authorize url -authorization_url = client.authorization_uri( - # Update scopes if needed - scope: [ - :'users.read', - :'tweet.read', - :'bookmark.read', - :'offline.access' - ] -) - -# Set code verifier and state -code_verifier = client.code_verifier -state = client.state - -# Visit the URL to authorize your App to make requests on behalf of a user -print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' -puts authorization_url -`open "#{authorization_url}"` - -print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush - -# Fetch your access token -full_text = gets.chop -new_code = full_text.split("code=") -code = new_code[1] -client.authorization_code = code - -# Your access token -token_response = client.access_token! code_verifier - -# Make a request to the users/me endpoint to get your user ID -def users_me(url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "BookmarksSampleCode", - "Authorization": "Bearer #{token_response}" - }, - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -url = "https://api.twitter.com/2/users/me" -me_response = users_me(url, token_response) - -json_s = JSON.parse(me_response.body) -user_id = json_s["data"]["id"] - -# Make a request to the bookmarks url -bookmarks_url = "https://api.twitter.com/2/users/#{user_id}/bookmarks" - -def bookmarked_tweets(bookmarks_url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "BookmarksSampleCode", - "Authorization": "Bearer #{token_response}" - } - } - - request = Typhoeus::Request.new(bookmarks_url, options) - response = request.run - - return response -end - -response = bookmarked_tweets(bookmarks_url, token_response) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Direct-Messages-lookup/get_events_by_conversation.py b/Direct-Messages-lookup/get_events_by_conversation.py deleted file mode 100644 index 19f1888..0000000 --- a/Direct-Messages-lookup/get_events_by_conversation.py +++ /dev/null @@ -1,107 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -# This example is set up to retrieve Direct Message events by conversation ID. This supports both -# one-to-one and group conversations. -GET_DMS_EVENTS_URL = "https://api.twitter.com/2/dm_conversations/:dm_conversation_id/dm_events" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = '' -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- -# This variable specifies the conversation to retrieve. A more ready-to-be used example would -# have this passed in from some calling code. -# What is the ID of the conversatikon to retrieve? -dm_conversation_id = "1512210732774948865" -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start and OAuth 2.0 session - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # Your access token - access = token["access_token"] - - return access - -def get_events_by_conservation_id(dm_conversation_id): - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = GET_DMS_EVENTS_URL.replace(':dm_conversation_id', str(dm_conversation_id)) - - response = requests.request("GET", request_url, headers=headers) - - if response.status_code != 200: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - return response - -def main(): - response = get_events_by_conservation_id(dm_conversation_id) - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Direct-Messages-lookup/get_one_to_one_conversation_events.py b/Direct-Messages-lookup/get_one_to_one_conversation_events.py deleted file mode 100644 index 73d17ef..0000000 --- a/Direct-Messages-lookup/get_one_to_one_conversation_events.py +++ /dev/null @@ -1,108 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -# This example is set up to retrieve Direct Message conversation events associated with a one-to-one message. -# Currently, the v2 DM endpoints support three conversation event types: MessageCreate, ParticipantsJoin, and -# ParticipantsLeave. -GET_DM_EVENTS_URL = "https://api.twitter.com/2/dm_conversations/with/:participant_id/dm_events" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = '' -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- -# This variable indicates the participant of the one-to-one conversation. A more ready-to-be used example would -# have this passed in from some calling code. -# Who is this one-to-one conversation with? -participant_id = "906948460078698496" -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start and OAuth 2.0 session - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # Your access token - access = token["access_token"] - - return access - -def get_one_to_one_conversation_events(participant_id): - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = GET_DM_EVENTS_URL.replace(':participant_id', str(participant_id)) - - response = requests.request("GET", request_url, headers=headers) - - if response.status_code != 200: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - return response - -def main(): - response = get_one_to_one_conversation_events(participant_id) - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Direct-Messages-lookup/get_user_conversation_events.py b/Direct-Messages-lookup/get_user_conversation_events.py deleted file mode 100644 index 6f272f6..0000000 --- a/Direct-Messages-lookup/get_user_conversation_events.py +++ /dev/null @@ -1,102 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -# This example is set up to retrieve Direct Message events of the authenticating user. This supports both -# one-to-one and group conversations. -GET_DM_EVENTS_URL = "https://api.twitter.com/2/dm_events" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = "" -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier. - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge. - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start an OAuth 2.0 session. - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL. - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user. - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request. - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token. - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client. - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # The access token. - access = token["access_token"] - - return access - -def get_user_conversation_events(): - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = GET_DM_EVENTS_URL - - response = requests.request("GET", request_url, headers=headers) - - if response.status_code != 200: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - return response - -def main(): - response = get_user_conversation_events() - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Filtered-Stream/FilteredStreamDemo.java b/Filtered-Stream/FilteredStreamDemo.java deleted file mode 100644 index ea23fb1..0000000 --- a/Filtered-Stream/FilteredStreamDemo.java +++ /dev/null @@ -1,183 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.util.EntityUtils; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.*; -import java.net.URISyntaxException; -import java.util.*; - -/* - * Sample code to demonstrate the use of the Filtered Stream endpoint - * */ -public class FilteredStreamDemo { - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - Map rules = new HashMap<>(); - rules.put("cats has:images", "cat images"); - rules.put("dogs has:images", "dog images"); - setupRules(bearerToken, rules); - connectStream(bearerToken); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the filtered stream endpoint and streams Tweets from it - * */ - private static void connectStream(String bearerToken) throws IOException, URISyntaxException { - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/stream"); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - BufferedReader reader = new BufferedReader(new InputStreamReader((entity.getContent()))); - String line = reader.readLine(); - while (line != null) { - System.out.println(line); - line = reader.readLine(); - } - } - - } - - /* - * Helper method to setup rules before streaming data - * */ - private static void setupRules(String bearerToken, Map rules) throws IOException, URISyntaxException { - List existingRules = getRules(bearerToken); - if (existingRules.size() > 0) { - deleteRules(bearerToken, existingRules); - } - createRules(bearerToken, rules); - } - - /* - * Helper method to create rules for filtering - * */ - private static void createRules(String bearerToken, Map rules) throws URISyntaxException, IOException { - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/stream/rules"); - - HttpPost httpPost = new HttpPost(uriBuilder.build()); - httpPost.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpPost.setHeader("content-type", "application/json"); - StringEntity body = new StringEntity(getFormattedString("{\"add\": [%s]}", rules)); - httpPost.setEntity(body); - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - if (null != entity) { - System.out.println(EntityUtils.toString(entity, "UTF-8")); - } - } - - /* - * Helper method to get existing rules - * */ - private static List getRules(String bearerToken) throws URISyntaxException, IOException { - List rules = new ArrayList<>(); - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/stream/rules"); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("content-type", "application/json"); - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - JSONObject json = new JSONObject(EntityUtils.toString(entity, "UTF-8")); - if (json.length() > 1) { - JSONArray array = (JSONArray) json.get("data"); - for (int i = 0; i < array.length(); i++) { - JSONObject jsonObject = (JSONObject) array.get(i); - rules.add(jsonObject.getString("id")); - } - } - } - return rules; - } - - /* - * Helper method to delete rules - * */ - private static void deleteRules(String bearerToken, List existingRules) throws URISyntaxException, IOException { - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/stream/rules"); - - HttpPost httpPost = new HttpPost(uriBuilder.build()); - httpPost.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpPost.setHeader("content-type", "application/json"); - StringEntity body = new StringEntity(getFormattedString("{ \"delete\": { \"ids\": [%s]}}", existingRules)); - httpPost.setEntity(body); - HttpResponse response = httpClient.execute(httpPost); - HttpEntity entity = response.getEntity(); - if (null != entity) { - System.out.println(EntityUtils.toString(entity, "UTF-8")); - } - } - - private static String getFormattedString(String string, List ids) { - StringBuilder sb = new StringBuilder(); - if (ids.size() == 1) { - return String.format(string, "\"" + ids.get(0) + "\""); - } else { - for (String id : ids) { - sb.append("\"" + id + "\"" + ","); - } - String result = sb.toString(); - return String.format(string, result.substring(0, result.length() - 1)); - } - } - - private static String getFormattedString(String string, Map rules) { - StringBuilder sb = new StringBuilder(); - if (rules.size() == 1) { - String key = rules.keySet().iterator().next(); - return String.format(string, "{\"value\": \"" + key + "\", \"tag\": \"" + rules.get(key) + "\"}"); - } else { - for (Map.Entry entry : rules.entrySet()) { - String value = entry.getKey(); - String tag = entry.getValue(); - sb.append("{\"value\": \"" + value + "\", \"tag\": \"" + tag + "\"}" + ","); - } - String result = sb.toString(); - return String.format(string, result.substring(0, result.length() - 1)); - } - } - -} diff --git a/Filtered-Stream/filtered_stream.js b/Filtered-Stream/filtered_stream.js deleted file mode 100644 index d998d87..0000000 --- a/Filtered-Stream/filtered_stream.js +++ /dev/null @@ -1,160 +0,0 @@ -// Open a realtime stream of Tweets, filtered according to rules -// https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/quick-start - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const rulesURL = 'https://api.twitter.com/2/tweets/search/stream/rules'; -const streamURL = 'https://api.twitter.com/2/tweets/search/stream'; - -// this sets up two rules - the value is the search terms to match on, and the tag is an identifier that -// will be applied to the Tweets return to show which rule they matched -// with a standard project with Basic Access, you can add up to 25 concurrent rules to your stream, and -// each rule can be up to 512 characters long - -// Edit rules as desired below -const rules = [{ - 'value': 'dog has:images -is:retweet', - 'tag': 'dog pictures' - }, - { - 'value': 'cat has:images -grumpy', - 'tag': 'cat pictures' - }, -]; - -async function getAllRules() { - - const response = await needle('get', rulesURL, { - headers: { - "authorization": `Bearer ${token}` - } - }) - - if (response.statusCode !== 200) { - console.log("Error:", response.statusMessage, response.statusCode) - throw new Error(response.body); - } - - return (response.body); -} - -async function deleteAllRules(rules) { - - if (!Array.isArray(rules.data)) { - return null; - } - - const ids = rules.data.map(rule => rule.id); - - const data = { - "delete": { - "ids": ids - } - } - - const response = await needle('post', rulesURL, data, { - headers: { - "content-type": "application/json", - "authorization": `Bearer ${token}` - } - }) - - if (response.statusCode !== 200) { - throw new Error(response.body); - } - - return (response.body); - -} - -async function setRules() { - - const data = { - "add": rules - } - - const response = await needle('post', rulesURL, data, { - headers: { - "content-type": "application/json", - "authorization": `Bearer ${token}` - } - }) - - if (response.statusCode !== 201) { - throw new Error(response.body); - } - - return (response.body); - -} - -function streamConnect(retryAttempt) { - - const stream = needle.get(streamURL, { - headers: { - "User-Agent": "v2FilterStreamJS", - "Authorization": `Bearer ${token}` - }, - timeout: 20000 - }); - - stream.on('data', data => { - try { - const json = JSON.parse(data); - console.log(json); - // A successful connection resets retry count. - retryAttempt = 0; - } catch (e) { - if (data.detail === "This stream is currently at the maximum allowed connection limit.") { - console.log(data.detail) - process.exit(1) - } else { - // Keep alive signal received. Do nothing. - } - } - }).on('err', error => { - if (error.code !== 'ECONNRESET') { - console.log(error.code); - process.exit(1); - } else { - // This reconnection logic will attempt to reconnect when a disconnection is detected. - // To avoid rate limits, this logic implements exponential backoff, so the wait time - // will increase if the client cannot reconnect to the stream. - setTimeout(() => { - console.warn("A connection error occurred. Reconnecting...") - streamConnect(++retryAttempt); - }, 2 ** retryAttempt) - } - }); - - return stream; - -} - - -(async () => { - let currentRules; - - try { - // Gets the complete list of rules currently applied to the stream - currentRules = await getAllRules(); - - // Delete all rules. Comment the line below if you want to keep your existing rules. - await deleteAllRules(currentRules); - - // Add rules to the stream. Comment the line below if you don't want to add new rules. - await setRules(); - - } catch (e) { - console.error(e); - process.exit(1); - } - - // Listen to the stream. - streamConnect(0); -})(); diff --git a/Filtered-Stream/filtered_stream.rb b/Filtered-Stream/filtered_stream.rb deleted file mode 100644 index 64d1965..0000000 --- a/Filtered-Stream/filtered_stream.rb +++ /dev/null @@ -1,144 +0,0 @@ -# This script contains methods to add, remove, and retrieve rules from your stream. -# It will also connect to the stream endpoint and begin outputting data. -# Run as-is, the script gives you the option to replace existing rules with new ones and begin streaming data - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -@bearer_token = ENV["BEARER_TOKEN"] - -@stream_url = "https://api.twitter.com/2/tweets/search/stream" -@rules_url = "https://api.twitter.com/2/tweets/search/stream/rules" - -@sample_rules = [ - { 'value': 'dog has:images', 'tag': 'dog pictures' }, - { 'value': 'cat has:images -grumpy', 'tag': 'cat pictures' }, -] - -# Add or remove values from the optional parameters below. Full list of parameters can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream -params = { - "expansions": "attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,geo.place_id,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "description", - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -# Get request to rules endpoint. Returns list of of active rules from your stream -def get_all_rules - @options = { - headers: { - "User-Agent": "v2FilteredStreamRuby", - "Authorization": "Bearer #{@bearer_token}" - } - } - - @response = Typhoeus.get(@rules_url, @options) - - raise "An error occurred while retrieving active rules from your stream: #{@response.body}" unless @response.success? - - @body = JSON.parse(@response.body) -end - -# Post request to add rules to your stream -def set_rules(rules) - return if rules.nil? - - @payload = { - add: rules - } - - @options = { - headers: { - "User-Agent": "v2FilteredStreamRuby", - "Authorization": "Bearer #{@bearer_token}", - "Content-type": "application/json" - }, - body: JSON.dump(@payload) - } - - @response = Typhoeus.post(@rules_url, @options) - raise "An error occurred while adding rules: #{@response.status_message}" unless @response.success? -end - -# Post request with a delete body to remove rules from your stream -def delete_all_rules(rules) - return if rules.nil? - - @ids = rules['data'].map { |rule| rule["id"] } - @payload = { - delete: { - ids: @ids - } - } - - @options = { - headers: { - "User-Agent": "v2FilteredStreamRuby", - "Authorization": "Bearer #{@bearer_token}", - "Content-type": "application/json" - }, - body: JSON.dump(@payload) - } - - @response = Typhoeus.post(@rules_url, @options) - - raise "An error occurred while deleting your rules: #{@response.status_message}" unless @response.success? -end - -# Helper method that gets active rules and prompts to delete (y/n), then adds new rules set in line 17 (@sample_rules) -def setup_rules - # Gets the complete list of rules currently applied to the stream - @rules = get_all_rules - puts "Found existing rules on the stream:\n #{@rules}\n" - - puts "Do you want to delete existing rules and replace with new rules? [y/n]" - answer = gets.chomp - if answer == "y" - # Delete all rules - delete_all_rules(@rules) - else - puts "Keeping existing rules and adding new ones." - end - - # Add rules to the stream - set_rules(@sample_rules) -end - -# Connects to the stream and returns data (Tweet payloads) in chunks -def stream_connect(params) - @options = { - timeout: 20, - method: 'get', - headers: { - "User-Agent": "v2FilteredStreamRuby", - "Authorization": "Bearer #{@bearer_token}" - }, - params: params - } - - @request = Typhoeus::Request.new(@stream_url, @options) - @request.on_body do |chunk| - puts chunk - end - @request.run -end - -# Comment this line if you already setup rules and want to keep them -setup_rules - -# Listen to the stream. -# This reconnection logic will attempt to reconnect when a disconnection is detected. -# To avoid rate limites, this logic implements exponential backoff, so the wait time -# will increase if the client cannot reconnect to the stream. -timeout = 0 -while true - stream_connect(params) - sleep 2 ** timeout - timeout += 1 -end \ No newline at end of file diff --git a/Follows-Lookup/FollowersLookupDemo.java b/Follows-Lookup/FollowersLookupDemo.java deleted file mode 100644 index aa99ba1..0000000 --- a/Follows-Lookup/FollowersLookupDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 followers lookup endpoint - * */ -public class FollowersLookupDemo { - - // To set your environment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - // Replace with user ID below - String response = getFollowers("2244994945", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 followers lookup endpoint by user ID - * */ - private static String getFollowers(String userId, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(String.format("https://api.twitter.com/2/users/%s/followers", userId)); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("user.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} diff --git a/Follows-Lookup/FollowingLookupDemo.java b/Follows-Lookup/FollowingLookupDemo.java deleted file mode 100644 index 12c9867..0000000 --- a/Follows-Lookup/FollowingLookupDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 following lookup endpoint - * */ -public class FollowingLookupDemo { - - // To set your environment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - // Replace with user ID below - String response = getFollowing("2244994945", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 following lookup endpoint - * */ - private static String getFollowing(String userId, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(String.format("https://api.twitter.com/2/users/%s/following", userId)); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("user.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} diff --git a/Follows-Lookup/followers-lookup.rb b/Follows-Lookup/followers-lookup.rb deleted file mode 100644 index 4d7fd62..0000000 --- a/Follows-Lookup/followers-lookup.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on macOS or Linux, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the user followers -endpoint_url = "https://api.twitter.com/2/users/:id/followers" - -# Specify the User ID for this request. -id = 2244994945 - -# Add or remove parameters below to adjust the query and response fields within the payload -query_params = { - "max_results" => 1000, - "user.fields" => "created_at" -} - -def get_followers(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent" => "v2RubyExampleCode", - "Authorization" => "Bearer #{bearer_token}", - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -endpoint_url = endpoint_url.gsub(':id',id.to_s()) - -response = get_followers(endpoint_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Follows-Lookup/followers_lookup.js b/Follows-Lookup/followers_lookup.js deleted file mode 100644 index 2fea9e7..0000000 --- a/Follows-Lookup/followers_lookup.js +++ /dev/null @@ -1,67 +0,0 @@ -// Fetch the followers of a user account, by ID -// https://developer.twitter.com/en/docs/twitter-api/users/follows/quick-start - -const needle = require('needle'); - -// this is the ID for @TwitterDev -const userId = 2244994945; -const url = `https://api.twitter.com/2/users/${userId}/followers`; -const bearerToken = process.env.BEARER_TOKEN; - -const getFollowers = async () => { - let users = []; - let params = { - "max_results": 1000, - "user.fields": "created_at" - } - - const options = { - headers: { - "User-Agent": "v2FollowersJS", - "authorization": `Bearer ${bearerToken}` - } - } - - let hasNextPage = true; - let nextToken = null; - console.log("Retrieving followers..."); - while (hasNextPage) { - let resp = await getPage(params, options, nextToken); - if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { - if (resp.data) { - users.push.apply(users, resp.data); - } - if (resp.meta.next_token) { - nextToken = resp.meta.next_token; - } else { - hasNextPage = false; - } - } else { - hasNextPage = false; - } - } - - console.log(users); - console.log(`Got ${users.length} users.`); - -} - -const getPage = async (params, options, nextToken) => { - if (nextToken) { - params.pagination_token = nextToken; - } - - try { - const resp = await needle('get', url, params, options); - - if (resp.statusCode != 200) { - console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); - return; - } - return resp.body; - } catch (err) { - throw new Error(`Request failed: ${err}`); - } -} - -getFollowers(); diff --git a/Follows-Lookup/following-lookup.rb b/Follows-Lookup/following-lookup.rb deleted file mode 100644 index f5719ea..0000000 --- a/Follows-Lookup/following-lookup.rb +++ /dev/null @@ -1,40 +0,0 @@ -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on macOS or Linux, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the user following API -endpoint_url = "https://api.twitter.com/2/users/:id/following" - -# Specify the User ID for this request. -id = 2244994945 - -# Add or remove parameters below to adjust the query and response fields within the payload -query_params = { - "max_results" => 1000, - "user.fields" => "created_at" -} - -def get_following(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent" => "v2RubyExampleCode", - "Authorization" => "Bearer #{bearer_token}", - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -endpoint_url = endpoint_url.gsub(':id',id.to_s()) - -response = get_following(endpoint_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Follows-Lookup/following_lookup.js b/Follows-Lookup/following_lookup.js deleted file mode 100644 index 8892f45..0000000 --- a/Follows-Lookup/following_lookup.js +++ /dev/null @@ -1,67 +0,0 @@ -// Fetch the users being followed by a specific account, by ID -// https://developer.twitter.com/en/docs/twitter-api/users/follows/quick-start - -const needle = require('needle'); - -// this is the ID for @TwitterDev -const userId = 2244994945; -const url = `https://api.twitter.com/2/users/${userId}/following`; -const bearerToken = process.env.BEARER_TOKEN; - -const getFollowing = async () => { - let users = []; - let params = { - "max_results": 1000, - "user.fields": "created_at" - } - - const options = { - headers: { - "User-Agent": "v2FollowingJS", - "Authorization": `Bearer ${bearerToken}` - } - } - - let hasNextPage = true; - let nextToken = null; - console.log("Retrieving users this user is following..."); - while (hasNextPage) { - let resp = await getPage(params, options, nextToken); - if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { - if (resp.data) { - users.push.apply(users, resp.data); - } - if (resp.meta.next_token) { - nextToken = resp.meta.next_token; - } else { - hasNextPage = false; - } - } else { - hasNextPage = false; - } - } - - console.log(users); - console.log(`Got ${users.length} users.`); - -} - -const getPage = async (params, options, nextToken) => { - if (nextToken) { - params.pagination_token = nextToken; - } - - try { - const resp = await needle('get', url, params, options); - - if (resp.statusCode != 200) { - console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); - return; - } - return resp.body; - } catch (err) { - throw new Error(`Request failed: ${err}`); - } -} - -getFollowing(); diff --git a/Full-Archive-Search/FullArchiveSearchDemo.java b/Full-Archive-Search/FullArchiveSearchDemo.java deleted file mode 100644 index 90b9b32..0000000 --- a/Full-Archive-Search/FullArchiveSearchDemo.java +++ /dev/null @@ -1,65 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Full archive search endpoint - * */ -public class FullArchiveSearchDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace the search term with a term of your choice - String response = search("from:TwitterDev OR from:SnowBotDev OR from:DailyNASA", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the full-archive search endpoint with a the search term passed to it as a query parameter - * */ - private static String search(String searchString, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/all"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("query", searchString)); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Full-Archive-Search/full-archive-search.js b/Full-Archive-Search/full-archive-search.js deleted file mode 100644 index f3fd13d..0000000 --- a/Full-Archive-Search/full-archive-search.js +++ /dev/null @@ -1,51 +0,0 @@ -// Search for public Tweets across the whole Twitter archive -// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/full-archive-search - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = 'https://api.twitter.com/2/tweets/search/all' - -async function getRequest() { - - // These are the parameters for the API request - // specify Tweet IDs to fetch, and any additional fields that are required - // by default, only the Tweet ID and text are returned - const params = { - 'query': 'from:twitterdev -is:retweet', - 'tweet.fields': 'author_id' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2FullArchiveJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Full-Archive-Search/full-archive-search.py b/Full-Archive-Search/full-archive-search.py deleted file mode 100644 index acb0a95..0000000 --- a/Full-Archive-Search/full-archive-search.py +++ /dev/null @@ -1,40 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -search_url = "https://api.twitter.com/2/tweets/search/all" - -# Optional params: start_time,end_time,since_id,until_id,max_results,next_token, -# expansions,tweet.fields,media.fields,poll.fields,place.fields,user.fields -query_params = {'query': '(from:twitterdev -is:retweet) OR #twitterdev','tweet.fields': 'author_id'} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2FullArchiveSearchPython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("GET", search_url, auth=bearer_oauth, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(search_url, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/Full-Archive-Search/full-archive-search.r b/Full-Archive-Search/full-archive-search.r deleted file mode 100644 index e08d7d8..0000000 --- a/Full-Archive-Search/full-archive-search.r +++ /dev/null @@ -1,26 +0,0 @@ -library(httr) - -# Replace the bearer token below with -bearer_token = "" - -headers = c( - `Authorization` = sprintf('Bearer %s', bearer_token) -) - -params = list( - `query` = 'from:twitterdev lang:en', - `max_results` = '10', - `tweet.fields` = 'created_at,lang,context_annotations' -) - -response <- httr::GET(url = 'https://api.twitter.com/2/tweets/search/all', httr::add_headers(.headers=headers), query = params) - -fas_body <- - content( - response, - as = 'parsed', - type = 'application/json', - simplifyDataFrame = TRUE - ) - -View(fas_body$data) \ No newline at end of file diff --git a/Full-Archive-Search/full-archive-search.rb b/Full-Archive-Search/full-archive-search.rb deleted file mode 100644 index 6dc9cd1..0000000 --- a/Full-Archive-Search/full-archive-search.rb +++ /dev/null @@ -1,49 +0,0 @@ -# This script uses your bearer token to authenticate and make a Search request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Full-archive Search API -search_url = "https://api.twitter.com/2/tweets/search/all" - -# Set the query value here. Value can be up to 512 characters -query = "from:Twitter OR from:TwitterDev OR from:DailyNasa" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all -query_params = { - "query": query, # Required - "max_results": 10, - # "start_time": "2020-07-01T00:00:00Z", - # "end_time": "2020-07-02T18:00:00Z", - # "expansions": "attachments.poll_ids,attachments.media_keys,author_id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,id,lang", - "user.fields": "description" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -def search_tweets(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2FullArchiveSearchRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = search_tweets(search_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Full-Archive-Tweet-Counts/FullArchiveTweetCountsDemo.java b/Full-Archive-Tweet-Counts/FullArchiveTweetCountsDemo.java deleted file mode 100644 index 0c62c8b..0000000 --- a/Full-Archive-Tweet-Counts/FullArchiveTweetCountsDemo.java +++ /dev/null @@ -1,67 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Full-archive Tweet counts endpoint - * */ -public class FullArchiveTweetCountsDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace the search term with a term of your choice - String response = getTweetCounts("from:TwitterDev", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the full-archive Tweet counts endpoint with a the search term passed to it as a query parameter - * */ - private static String getTweetCounts(String searchString, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/counts/all"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("query", searchString)); - queryParameters.add(new BasicNameValuePair("granularity", "day")); - queryParameters.add(new BasicNameValuePair("start_time", "2021-01-01T00:00:00Z")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.js b/Full-Archive-Tweet-Counts/full_archive_tweet_counts.js deleted file mode 100644 index f1c2b82..0000000 --- a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.js +++ /dev/null @@ -1,51 +0,0 @@ -// Search for public Tweets across the whole Twitter archive -// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/full-archive-search - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = 'https://api.twitter.com/2/tweets/counts/all' - -async function getRequest() { - - // Edit query parameters below and specify a search query - // optional params: start_time,end_time,since_id,until_id,next_token,granularity - const params = { - 'query': 'from:twitterdev', - 'granularity': 'day', - 'start_time': '2021-01-01T00:00:00Z' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2FullArchiveTweetCountsJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.py b/Full-Archive-Tweet-Counts/full_archive_tweet_counts.py deleted file mode 100644 index 0476e03..0000000 --- a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.py +++ /dev/null @@ -1,39 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -search_url = "https://api.twitter.com/2/tweets/counts/all" - -# Optional params: start_time,end_time,since_id,until_id,next_token,granularity -query_params = {'query': 'from:twitterdev','granularity': 'day', 'start_time': '2021-01-01T00:00:00Z'} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2FullArchiveTweetCountsPython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("GET", search_url, auth=bearer_oauth, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(search_url, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.r b/Full-Archive-Tweet-Counts/full_archive_tweet_counts.r deleted file mode 100644 index 421f79f..0000000 --- a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.r +++ /dev/null @@ -1,25 +0,0 @@ -library(httr) - -# Replace the bearer token below with -bearer_token = "" - -headers = c( - `Authorization` = sprintf('Bearer %s', bearer_token) -) - -params = list( - `query` = 'from:twitterdev', - `granularity` = 'day' -) - -response <- httr::GET(url = 'https://api.twitter.com/2/tweets/counts/all', httr::add_headers(.headers=headers), query = params) - -body <- - content( - response, - as = 'parsed', - type = 'application/json', - simplifyDataFrame = TRUE - ) - -View(body$data) \ No newline at end of file diff --git a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.rb b/Full-Archive-Tweet-Counts/full_archive_tweet_counts.rb deleted file mode 100644 index 7bed9d5..0000000 --- a/Full-Archive-Tweet-Counts/full_archive_tweet_counts.rb +++ /dev/null @@ -1,42 +0,0 @@ -# This script uses your bearer token to authenticate and make a Search request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Full-archive Search API -search_url = "https://api.twitter.com/2/tweets/counts/all" - -# Set the query value here. Value can be up to 1024 characters -query = "from:TwitterDev" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-counts-all -query_params = { - "query": query, # Required - "start_time": "2021-01-01T00:00:00Z", - "granularity": "day" -} - -def get_tweet_counts(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2FullArchiveTweetCountsRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = get_tweet_counts(search_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Likes-Lookup/liked_tweets.js b/Likes-Lookup/liked_tweets.js deleted file mode 100644 index 2b0f668..0000000 --- a/Likes-Lookup/liked_tweets.js +++ /dev/null @@ -1,46 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "your-user-id"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/liked_tweets`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the Tweet ID and text are returned - const params = { - "tweet.fields": "lang,author_id", // Edit optional query parameters here - "user.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2LikedTweetsJS", - authorization: `Bearer ${token}` - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Likes-Lookup/liked_tweets.py b/Likes-Lookup/liked_tweets.py deleted file mode 100644 index 5b05cc2..0000000 --- a/Likes-Lookup/liked_tweets.py +++ /dev/null @@ -1,58 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - tweet_fields = "tweet.fields=lang,author_id" - # Be sure to replace your-user-id with your own user ID or one of an authenticating user - # You can find a user ID by using the user lookup endpoint - id = "your-user-id" - # You can adjust ids to include a single Tweets. - # Or you can add to up to 100 comma-separated IDs - url = "https://api.twitter.com/2/users/{}/liked_tweets".format(id) - return url, tweet_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2LikedTweetsPython" - return r - - -def connect_to_endpoint(url, tweet_fields): - response = requests.request( - "GET", url, auth=bearer_oauth, params=tweet_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, tweet_fields = create_url() - json_response = connect_to_endpoint(url, tweet_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Likes-Lookup/liked_tweets.rb b/Likes-Lookup/liked_tweets.rb deleted file mode 100644 index be3a9a9..0000000 --- a/Likes-Lookup/liked_tweets.rb +++ /dev/null @@ -1,45 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" -url = "https://api.twitter.com/2/users/#{id}/liked_tweets" - - -params = { - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - "tweet.fields": "lang,author_id", -} - -def liked_tweets(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2LikedTweetsRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = liked_tweets(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Likes-Lookup/liking_users.js b/Likes-Lookup/liking_users.js deleted file mode 100644 index d79d9b0..0000000 --- a/Likes-Lookup/liking_users.js +++ /dev/null @@ -1,49 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; - -// You can replace the ID given with the Tweet ID you wish to like. -// You can find an ID by using the Tweet lookup endpoint -const id = "1354143047324299264"; - -const endpointURL = `https://api.twitter.com/2/tweets/${id}/liking_users`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the Tweet ID and text are returned - const params = { - "tweet.fields": "lang,author_id", // Edit optional query parameters here - "user.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2LikingUsersJS", - authorization: `Bearer ${token}` - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Likes-Lookup/liking_users.py b/Likes-Lookup/liking_users.py deleted file mode 100644 index 01079d5..0000000 --- a/Likes-Lookup/liking_users.py +++ /dev/null @@ -1,54 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - user_fields = "user.fields=created_at,description" - # You can replace the ID given with the Tweet ID you wish to like. - # You can find an ID by using the Tweet lookup endpoint - id = "1354143047324299264" - # You can adjust ids to include a single Tweets. - # Or you can add to up to 100 comma-separated IDs - url = "https://api.twitter.com/2/tweets/{}/liking_users".format(id) - return url, user_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2LikingUsersPython" - return r - - -def connect_to_endpoint(url, user_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, tweet_fields = create_url() - json_response = connect_to_endpoint(url, tweet_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Likes-Lookup/liking_users.rb b/Likes-Lookup/liking_users.rb deleted file mode 100644 index e4133fb..0000000 --- a/Likes-Lookup/liking_users.rb +++ /dev/null @@ -1,43 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - - -# You can replace the ID given with the Tweet ID you wish to like. -# You can find an ID by using the Tweet lookup endpoint -id = "1354143047324299264" - -url = "https://api.twitter.com/2/tweets/#{id}/liking_users" - -params = { - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - "user.fields": "created_at,description", -} - -def liking_users(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2LikingUsersRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = liking_users(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/List-Tweets-lookup/List-Tweets.py b/List-lookup/List-Tweets-lookup/List-Tweets.py deleted file mode 100644 index 847d917..0000000 --- a/List-lookup/List-Tweets-lookup/List-Tweets.py +++ /dev/null @@ -1,55 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - tweet_fields = "tweet.fields=lang,author_id" - # Be sure to replace list-id with any List ID - id = "list-id" - url = "https://api.twitter.com/2/lists/{}/tweets".format(id) - return url, tweet_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2ListTweetsLookupPython" - return r - - -def connect_to_endpoint(url, tweet_fields): - response = requests.request( - "GET", url, auth=bearer_oauth, params=tweet_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, tweet_fields = create_url() - json_response = connect_to_endpoint(url, tweet_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/List-Tweets-lookup/List-Tweets.rb b/List-lookup/List-Tweets-lookup/List-Tweets.rb deleted file mode 100644 index 80f309b..0000000 --- a/List-lookup/List-Tweets-lookup/List-Tweets.rb +++ /dev/null @@ -1,44 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified Tweet objects (by List ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace list-id with any List ID -id = "list-id" -url = "https://api.twitter.com/2/lists/#{id}/tweets" - - -params = { - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - "tweet.fields": "lang,author_id", -} - -def list_tweets(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2ListTweetsLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = list_tweets(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/List-Tweets-lookup/List-tweets.js b/List-lookup/List-Tweets-lookup/List-tweets.js deleted file mode 100644 index 06a4b03..0000000 --- a/List-lookup/List-Tweets-lookup/List-tweets.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${id}/tweets`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the Tweet ID and text are returned - const params = { - "tweet.fields": "lang,author_id", // Edit optional query parameters here - expansions: "author_id", // expansions is used to include the user object - "user.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2ListTweetsLookupJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/List-follows-lookup/list-followers-lookup.js b/List-lookup/List-follows-lookup/list-followers-lookup.js deleted file mode 100644 index cac4f15..0000000 --- a/List-lookup/List-follows-lookup/list-followers-lookup.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${id}/followers`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the User ID and name are returned - const params = { - "user.fields": "pinned_tweet_id,created_at", // Edit optional query parameters here - expansions: "pinned_tweet_id", // expansions is used to include the Tweet object - "tweet.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2ListFollowersLookupJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/List-follows-lookup/list-followers-lookup.py b/List-lookup/List-follows-lookup/list-followers-lookup.py deleted file mode 100644 index db36cae..0000000 --- a/List-lookup/List-follows-lookup/list-followers-lookup.py +++ /dev/null @@ -1,51 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - user_fields = "user.fields=created_at,description,verified" - # You can replace list-id with the List ID you wish to find followers of. - id = "list-id" - url = "https://api.twitter.com/2/lists/{}/followers".format(id) - return url, user_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2ListFollowersLookupPython" - return r - - -def connect_to_endpoint(url, user_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, user_fields = create_url() - json_response = connect_to_endpoint(url, user_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/List-follows-lookup/list-followers-lookup.rb b/List-lookup/List-follows-lookup/list-followers-lookup.rb deleted file mode 100644 index 0e2b2d7..0000000 --- a/List-lookup/List-follows-lookup/list-followers-lookup.rb +++ /dev/null @@ -1,41 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve followers of a List specified by List ID - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace list-id with any List ID -id = "list-id" -url = "https://api.twitter.com/2/lists/#{id}/followers" - - -params = { - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - "user.fields": "created_at,verified", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2ListFollowersLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/List-follows-lookup/user-list-followed.js b/List-lookup/List-follows-lookup/user-list-followed.js deleted file mode 100644 index 57b151b..0000000 --- a/List-lookup/List-follows-lookup/user-list-followed.js +++ /dev/null @@ -1,48 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "user-id"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/followed_lists`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the List ID and name are returned - const params = { - "list.fields": "owner_id", // Edit optional query parameters here - expansions: "owner_id", // expansions is used to include the user object - "user.fields": "created_at,verified", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2userListMembershipsJS", - authorization: `Bearer ${token}`, - "x-des-apiservices": "staging1", - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/List-follows-lookup/user-list-followed.py b/List-lookup/List-follows-lookup/user-list-followed.py deleted file mode 100644 index 448efb5..0000000 --- a/List-lookup/List-follows-lookup/user-list-followed.py +++ /dev/null @@ -1,50 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - list_fields = "list.fields=created_at,follower_count" - # You can replace the user-id with any valid User ID you wish to find what Lists they are following. - id = "user-id" - url = "https://api.twitter.com/2/users/{}/followed_lists".format(id) - return url, list_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2userListMembershipsPython" - return r - - -def connect_to_endpoint(url, list_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, list_fields = create_url() - json_response = connect_to_endpoint(url, list_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/List-follows-lookup/user-list-followed.rb b/List-lookup/List-follows-lookup/user-list-followed.rb deleted file mode 100644 index e4bd02d..0000000 --- a/List-lookup/List-follows-lookup/user-list-followed.rb +++ /dev/null @@ -1,40 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified List objects (by user ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace user-id with any User ID -id = "user-id" -url = "https://api.twitter.com/2/users/#{id}/followed_lists" - - -params = { - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - "list.fields": "created_at,private", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2userMembershipsRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/List-members-lookup/list-member-lookup.js b/List-lookup/List-members-lookup/list-member-lookup.js deleted file mode 100644 index bab37fb..0000000 --- a/List-lookup/List-members-lookup/list-member-lookup.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${id}/members`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the User ID and name are returned - const params = { - "user.fields": "pinned_tweet_id,created_at", // Edit optional query parameters here - expansions: "pinned_tweet_id", // expansions is used to include the Tweet object - "tweet.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2ListMembersLookupJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/List-members-lookup/list-member-lookup.py b/List-lookup/List-members-lookup/list-member-lookup.py deleted file mode 100644 index a10fca3..0000000 --- a/List-lookup/List-members-lookup/list-member-lookup.py +++ /dev/null @@ -1,50 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - user_fields = "user.fields=created_at,description,verified" - # You can replace list-id with the List ID you wish to find members of. - id = "list-id" - url = "https://api.twitter.com/2/lists/{}/members".format(id) - return url, user_fields - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2ListMembersLookupPython" - return r - - -def connect_to_endpoint(url, user_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, user_fields = create_url() - json_response = connect_to_endpoint(url, user_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/List-members-lookup/list-member-lookup.rb b/List-lookup/List-members-lookup/list-member-lookup.rb deleted file mode 100644 index 7ba4029..0000000 --- a/List-lookup/List-members-lookup/list-member-lookup.rb +++ /dev/null @@ -1,41 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve members of a List specified by List ID - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace list-id with any List ID -id = "list-id" -url = "https://api.twitter.com/2/lists/#{id}/members" - - -params = { - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - "user.fields": "created_at,verified", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2ListMembersLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/List-members-lookup/user-list-memberships.js b/List-lookup/List-members-lookup/user-list-memberships.js deleted file mode 100644 index 5bdf590..0000000 --- a/List-lookup/List-members-lookup/user-list-memberships.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "user-id"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/list_memberships`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the List ID and name are returned - const params = { - "list.fields": "owner_id", // Edit optional query parameters here - expansions: "owner_id", // expansions is used to include the user object - "user.fields": "created_at,verified", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2userListMembershipsJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/List-members-lookup/user-list-memberships.py b/List-lookup/List-members-lookup/user-list-memberships.py deleted file mode 100644 index a8440db..0000000 --- a/List-lookup/List-members-lookup/user-list-memberships.py +++ /dev/null @@ -1,50 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - list_fields = "list.fields=created_at,follower_count" - # You can replace the user-id with any valid User ID you wish to find what Lists they are members of. - id = "user-id" - url = "https://api.twitter.com/2/users/{}/list_memberships".format(id) - return url, list_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2userListMembershipsPython" - return r - - -def connect_to_endpoint(url, list_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, list_fields = create_url() - json_response = connect_to_endpoint(url, list_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/List-members-lookup/user-list-memberships.rb b/List-lookup/List-members-lookup/user-list-memberships.rb deleted file mode 100644 index 5d065a6..0000000 --- a/List-lookup/List-members-lookup/user-list-memberships.rb +++ /dev/null @@ -1,40 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified List objects (by user ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace user-id with any User ID -id = "user-id" -url = "https://api.twitter.com/2/users/#{id}/list_memberships" - - -params = { - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - "list.fields": "created_at,private", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2userMembershipsRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/Pinned-Lists-lookup/Pinned-List.js b/List-lookup/Pinned-Lists-lookup/Pinned-List.js deleted file mode 100644 index 1f52c40..0000000 --- a/List-lookup/Pinned-Lists-lookup/Pinned-List.js +++ /dev/null @@ -1,150 +0,0 @@ -// Pin a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const needle = require("needle"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -const params = { - "list.fields": `owner_id`, // Edit optional query parameters here - expansions: `owner_id`, // expansions is used to include the user object - "user.fields": `created_at,verified`, // Edit optional query parameters here -}; - -const endpointURL = `https://api.twitter.com/2/users/${id}/pinned_lists`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "GET", - }, - token - ) - ); - - const req = await needle("get", endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2pinListLookupJS", - "content-type": "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/Pinned-Lists-lookup/Pinned-List.rb b/List-lookup/Pinned-Lists-lookup/Pinned-List.rb deleted file mode 100644 index d858449..0000000 --- a/List-lookup/Pinned-Lists-lookup/Pinned-List.rb +++ /dev/null @@ -1,89 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -url = "https://api.twitter.com/2/users/#{id}/pinned_lists" - -@params = { - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - "list.fields": "created_at,follower_count" -} - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def pin_list(url, oauth_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2pinListLookupRuby", - "content-type": "application/json" - }, - params: @params - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = pin_list(url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/list-lookup-by-id.js b/List-lookup/list-lookup-by-id.js deleted file mode 100644 index 8c562ac..0000000 --- a/List-lookup/list-lookup-by-id.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${id}`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the List ID and name are returned - const params = { - "list.fields": "owner_id", // Edit optional query parameters here - expansions: "owner_id", // expansions is used to include the user object - "user.fields": "created_at,verified", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2ListLookupJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/list-lookup-by-id.py b/List-lookup/list-lookup-by-id.py deleted file mode 100644 index abbee5f..0000000 --- a/List-lookup/list-lookup-by-id.py +++ /dev/null @@ -1,50 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - list_fields = "list.fields=created_at,follower_count" - # You can replace the ID given with the List ID you wish to lookup. - id = "list-id" - url = "https://api.twitter.com/2/lists/{}".format(id) - return url, list_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2ListLookupPython" - return r - - -def connect_to_endpoint(url, list_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, list_fields = create_url() - json_response = connect_to_endpoint(url, list_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/list-lookup-by-id.rb b/List-lookup/list-lookup-by-id.rb deleted file mode 100644 index 66b529b..0000000 --- a/List-lookup/list-lookup-by-id.rb +++ /dev/null @@ -1,40 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified List objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Be sure to replace list-id with any List ID -id = "list-id" -url = "https://api.twitter.com/2/lists/#{id}" - - -params = { - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - "list.fields": "created_at,follower_count", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2ListLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/List-lookup/user-owned-list-lookup.js b/List-lookup/user-owned-list-lookup.js deleted file mode 100644 index e36444c..0000000 --- a/List-lookup/user-owned-list-lookup.js +++ /dev/null @@ -1,47 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; -const id = "user-id"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/owned_lists`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the List ID and name are returned - const params = { - "list.fields": "owner_id", // Edit optional query parameters here - expansions: "owner_id", // expansions is used to include the user object - "user.fields": "created_at,verified", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2ListLookupJS", - authorization: `Bearer ${token}`, - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/List-lookup/user-owned-list-lookup.py b/List-lookup/user-owned-list-lookup.py deleted file mode 100644 index 0b49b7b..0000000 --- a/List-lookup/user-owned-list-lookup.py +++ /dev/null @@ -1,50 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - list_fields = "list.fields=created_at,follower_count" - # You can replace user-id with any valid User ID to see if they own any Lists. - id = "user-id" - url = "https://api.twitter.com/2/users/{}/owned_lists".format(id) - return url, list_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2ListLookupPython" - return r - - -def connect_to_endpoint(url, list_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, list_fields = create_url() - json_response = connect_to_endpoint(url, list_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/List-lookup/user-owned-list-lookup.rb b/List-lookup/user-owned-list-lookup.rb deleted file mode 100644 index a447f34..0000000 --- a/List-lookup/user-owned-list-lookup.rb +++ /dev/null @@ -1,40 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve any user owned Lists specified by user ID - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - - # You can replace the ID with the User ID to see if they own any Lists. -id = "user-id" -url = "https://api.twitter.com/2/users/#{id}/owned_lists" - - -params = { - # List fields are adjustable, options include: - # created_at, description, owner_id, - # private, follower_count, member_count, - "list.fields": "created_at,follower_count", -} - -def lists(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2ListLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = lists(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Blocks/block_a_user.js b/Manage-Blocks/block_a_user.js deleted file mode 100644 index 08e4a6c..0000000 --- a/Manage-Blocks/block_a_user.js +++ /dev/null @@ -1,150 +0,0 @@ -// Block a user, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to add replace id-to-block with the user id you wish to block. -// You can find a user ID by using the user lookup endpoint -const data = { - "target_user_id": "id-to-block" -} - -const endpointURL = `https://api.twitter.com/2/users/${id}/blocking`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'POST' - }, token)); - - const req = await got.post(endpointURL, { - json: data, - responseType: 'json', - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2BlockUserJS", - 'content-type': "application/json", - 'accept': "application/json" - } - }); - if (req.body) { - return req.body; - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Blocks/block_a_user.rb b/Manage-Blocks/block_a_user.rb deleted file mode 100644 index 399b0b0..0000000 --- a/Manage-Blocks/block_a_user.rb +++ /dev/null @@ -1,86 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" -blocking_url = "https://api.twitter.com/2/users/#{id}/blocking" - -# Be sure to add replace id-to-block with the id of the user you wish to block. -# You can find a user ID by using the user lookup endpoint -@target_user_id = { "target_user_id": "id-to-block" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_block(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2BlockUserRuby", - "content-type": "application/json" - }, - body: JSON.dump(@target_user_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = user_block(blocking_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Blocks/unblock_a_user.js b/Manage-Blocks/unblock_a_user.js deleted file mode 100644 index bd59d18..0000000 --- a/Manage-Blocks/unblock_a_user.js +++ /dev/null @@ -1,149 +0,0 @@ -// Unblock a user, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const source_user_id = "your-user-id"; - - -// Be sure to add replace the id-to-unblock with the user id of the you wish to unblock. -// You can find a user ID by using the user lookup endpoint -const target_user_id = "id-to-unblock" - -const endpointURL = `https://api.twitter.com/2/users/${source_user_id}/blocking/${target_user_id}`; - - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'DELETE' - }, token)); - - const req = await got.post(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UnblockUserJS" - } - }); - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); - - -// Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/Manage-Blocks/unblock_a_user.py b/Manage-Blocks/unblock_a_user.py deleted file mode 100644 index b76c756..0000000 --- a/Manage-Blocks/unblock_a_user.py +++ /dev/null @@ -1,81 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - - -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -source_user_id = "your-user-id" - -# Be sure to add replace id-to-unblock with the id of the user you wish to unblock. -# You can find a user ID by using the user lookup endpoint -target_user_id = "id-to-unblock" - - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.delete( - "https://api.twitter.com/2/users/{}/blocking/{}".format(id, target_user_id) -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) - -# Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/Manage-Blocks/unblock_a_user.rb b/Manage-Blocks/unblock_a_user.rb deleted file mode 100644 index 68a8710..0000000 --- a/Manage-Blocks/unblock_a_user.rb +++ /dev/null @@ -1,86 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) - -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -source_user_id = "your-user-id" - -# Be sure to add replace id-to-unblock with the user id of the user you wish to unblock. -# You can find a user ID by using the user lookup endpoint -target_user_id = "id-to-unblock" - -# Returns a user object for one or more users specified by the requested usernames -user_unblock_url = "https://api.twitter.com/2/users/#{source_user_id}/blocking/#{target_user_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_unblock(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2UnblockUserRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = user_unblock(user_unblock_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) - -# Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/Manage-Bookmarks/create-bookmark-js-sdk.js b/Manage-Bookmarks/create-bookmark-js-sdk.js deleted file mode 100644 index 8c28b34..0000000 --- a/Manage-Bookmarks/create-bookmark-js-sdk.js +++ /dev/null @@ -1,93 +0,0 @@ -const { Client, auth } = require("twitter-api-sdk"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -//Helper function to parse callback -const getQueryStringParams = (query) => { - return query - ? (/^[?#]/.test(query) ? query.slice(1) : query) - .split(/[\?\&]/) - .reduce((params, param) => { - let [key, value] = param.split("="); - params[key] = value - ? decodeURIComponent(value.replace(/\+/g, " ")) - : ""; - return params; - }, {}) - : {}; -}; - -//Helper terminal input function -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CLIENT_ID='YOUR-CLIENT-ID' -// export CLIENET_SECRET='YOUR-CLIENT-SECRET' -const CLIENT_ID = process.env.CLIENT_ID; -const CLIENT_SECRET = process.env.CLIENT_SECRET; - -// Include the ID of the Tweet you wish to bookmark -const params = { - tweet_id: "replace-with-tweet-id", -}; - -(async () => { - const authClient = new auth.OAuth2User({ - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - callback: "https://www.example.com/oauth", - scopes: ["tweet.read", "users.read", "bookmark.write"], - }); - - const client = new Client(authClient); - const STATE = "my-state"; - - //Get authorization - const authUrl = authClient.generateAuthURL({ - state: STATE, - code_challenge: "challenge", - }); - - console.log(`Please go here and authorize:`, authUrl); - - //Input users callback url in termnial - const redirectCallback = await input("Paste the redirected callback here: "); - - try { - //Parse callback - const { state, code } = getQueryStringParams(redirectCallback); - if (state !== STATE) { - console.log("State isn't matching"); - } - //Gets access token - await authClient.requestAccessToken(code); - - //Get the user ID - const { - data: { id }, - } = await client.users.findMyUser(); - - //Makes api call - const postBookmark = await client.bookmarks.postUsersIdBookmarks( - id, - params - ); - console.dir(postBookmark, { - depth: null, - }); - process.exit(); - } catch (error) { - console.log(error); - } -})(); diff --git a/Manage-Bookmarks/create_bookmark.py b/Manage-Bookmarks/create_bookmark.py deleted file mode 100644 index d998cd1..0000000 --- a/Manage-Bookmarks/create_bookmark.py +++ /dev/null @@ -1,107 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests.auth import AuthBase, HTTPBasicAuth -from requests_oauthlib import OAuth2Session - -# Replace with a Tweet ID you want to Bookmark -tweet_to_bookmark = {"tweet_id": "1460323737035677698"} - -# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = os.environ.get("CLIENT_ID") - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = os.environ.get("CLIENT_SECRET") - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Set the scopes -scopes = ["bookmark.write", "tweet.read", "users.read", "offline.access"] - -# Create a code verifier -code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") -code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - -# Create a code challenge -code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() -code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") -code_challenge = code_challenge.replace("=", "") - -# Start and OAuth 2.0 session -oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - -# Create an authorize URL -auth_url = "https://twitter.com/i/oauth2/authorize" -authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" -) - -# Visit the URL to authorize your App to make requests on behalf of a user -print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" -) -print(authorization_url) - -# Paste in your authorize URL to complete the request -authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" -) - -# Fetch your access token -token_url = "https://api.twitter.com/2/oauth2/token" - -# The following line of code will only work if you are using a type of App that is a public client -auth = False - -# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. - -# Please remove the comment on the following line if you are using a type of App that is a confidential client -# auth = HTTPBasicAuth(client_id, client_secret) - -token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, -) - -# Your access token -access = token["access_token"] - -# Make a request to the users/me endpoint to get your user ID -user_me = requests.request( - "GET", - "https://api.twitter.com/2/users/me", - headers={"Authorization": "Bearer {}".format(access)}, -).json() -user_id = user_me["data"]["id"] - -# Make a request to the bookmarks url -url = "https://api.twitter.com/2/users/{}/bookmarks".format(user_id) -headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "BookmarksSampleCode", -} -response = requests.request("POST", url, headers=headers, json=tweet_to_bookmark) -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Bookmarks/create_bookmark.rb b/Manage-Bookmarks/create_bookmark.rb deleted file mode 100644 index a13ed31..0000000 --- a/Manage-Bookmarks/create_bookmark.rb +++ /dev/null @@ -1,113 +0,0 @@ -require 'json' -require 'typhoeus' -require 'twitter_oauth2' - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = ENV["CLIENT_ID"] - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = ENV["CLIENT_SECRET"] - - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Replace with a Tweet ID you want to Bookmark -@json_payload = {"tweet_id": "1460323737035677698"} - -# Start an OAuth 2.0 session with a public client -client = TwitterOAuth2::Client.new( - identifier: "#{client_id}", - redirect_uri: "#{redirect_uri}" -) - -# Start an OAuth 2.0 session with a confidential client -# Remove the comment on the following lines if you are using a confidential client -# client = TwitterOAuth2::Client.new( -# identifier: "#{client_id}", -# secret: "#{client_secret}", -# redirect_uri: "#{redirect_uri}" -# ) - -# Create your authorize url -authorization_url = client.authorization_uri( - scope: [ - :'users.read', - :'tweet.read', - :'bookmark.write', - :'offline.access' - ] -) - -# Set code verifier and state -code_verifier = client.code_verifier -state = client.state - -# Visit the URL to authorize your App to make requests on behalf of a user -print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' -puts authorization_url -`open "#{authorization_url}"` - -print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush - -# Fetch your access token -full_text = gets.chop -new_code = full_text.split("code=") -code = new_code[1] -client.authorization_code = code - -# Your access token -token_response = client.access_token! code_verifier - -# Make a request to the users/me endpoint to get your user ID -def users_me(url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "BookmarksSampleCode", - "Authorization": "Bearer #{token_response}" - }, - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -url = "https://api.twitter.com/2/users/me" -me_response = users_me(url, token_response) - -json_s = JSON.parse(me_response.body) -user_id = json_s["data"]["id"] - -# Make a request to the bookmarks url -bookmarks_url = "https://api.twitter.com/2/users/#{user_id}/bookmarks" - -def bookmarked_tweets(bookmarks_url, token_response) - options = { - method: 'post', - headers: { - "User-Agent": "BookmarksSampleCode", - "content-type": "application/json", - "Authorization": "Bearer #{token_response}" - }, - body: JSON.dump(@json_payload) - } - - request = Typhoeus::Request.new(bookmarks_url, options) - response = request.run - - return response -end - -response = bookmarked_tweets(bookmarks_url, token_response) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Bookmarks/delete-bookmark-js-sdk.js b/Manage-Bookmarks/delete-bookmark-js-sdk.js deleted file mode 100644 index 91a5625..0000000 --- a/Manage-Bookmarks/delete-bookmark-js-sdk.js +++ /dev/null @@ -1,91 +0,0 @@ -const { Client, auth } = require("twitter-api-sdk"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -//Helper function to parse callback -const getQueryStringParams = (query) => { - return query - ? (/^[?#]/.test(query) ? query.slice(1) : query) - .split(/[\?\&]/) - .reduce((params, param) => { - let [key, value] = param.split("="); - params[key] = value - ? decodeURIComponent(value.replace(/\+/g, " ")) - : ""; - return params; - }, {}) - : {}; -}; - -//Helper terminal input function -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CLIENT_ID='YOUR-CLIENT-ID' -// export CLIENET_SECRET='YOUR-CLIENT-SECRET' -const CLIENT_ID = process.env.CLIENT_ID; -const CLIENT_SECRET = process.env.CLIENT_SECRET; - -// Include the ID of the Tweet you wish to unbookmark -const tweetId = "replace-with-tweet-id"; - -(async () => { - const authClient = new auth.OAuth2User({ - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - callback: "https://www.example.com/oauth", - scopes: ["tweet.read", "users.read", "bookmark.write"], - }); - - const client = new Client(authClient); - const STATE = "my-state"; - - //Get authorization - const authUrl = authClient.generateAuthURL({ - state: STATE, - code_challenge: "challenge", - }); - - console.log(`Please go here and authorize:`, authUrl); - - //Input users callback url in termnial - const redirectCallback = await input("Paste the redirected callback here: "); - - try { - //Parse callback - const { state, code } = getQueryStringParams(redirectCallback); - if (state !== STATE) { - console.log("State isn't matching"); - } - //Gets access token - await authClient.requestAccessToken(code); - - //Get the user ID - const { - data: { id }, - } = await client.users.findMyUser(); - - //Makes api call - const deleteBookmark = await client.bookmarks.usersIdBookmarksDelete( - id, - tweetId - ); - console.dir(deleteBookmark, { - depth: null, - }); - process.exit(); - } catch (error) { - console.log(error); - } -})(); diff --git a/Manage-Bookmarks/delete_bookmark.py b/Manage-Bookmarks/delete_bookmark.py deleted file mode 100644 index 7bd2d49..0000000 --- a/Manage-Bookmarks/delete_bookmark.py +++ /dev/null @@ -1,109 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests.auth import AuthBase, HTTPBasicAuth -from requests_oauthlib import OAuth2Session - -# Replace with a Tweet ID you want to remove Bookmark of -bookmarked_tweet_id = "1460323737035677698" - -# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = os.environ.get("CLIENT_ID") - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = os.environ.get("CLIENT_SECRET") - - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Set the scopes -scopes = ["bookmark.write", "tweet.read", "users.read", "offline.access"] - -# Create a code verifier -code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") -code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - -# Create a code challenge -code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() -code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") -code_challenge = code_challenge.replace("=", "") - -# Start and OAuth 2.0 session -oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - -# Create an authorize URL -auth_url = "https://twitter.com/i/oauth2/authorize" -authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" -) - -# Visit the URL to authorize your App to make requests on behalf of a user -print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" -) -print(authorization_url) - -# Paste in your authorize URL to complete the request -authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" -) - -# Fetch your access token -token_url = "https://api.twitter.com/2/oauth2/token" - -# The following line of code will only work if you are using a type of App that is a public client -auth = False - -# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. - -# Please remove the comment on the following line if you are using a type of App that is a confidential client -# auth = HTTPBasicAuth(client_id, client_secret) - -token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, -) - -# Your access token -access = token["access_token"] - -# Make a request to the users/me endpoint to get the user ID of the authenticated user -user_me = requests.request( - "GET", - "https://api.twitter.com/2/users/me", - headers={"Authorization": "Bearer {}".format(access)}, -).json() -user_id = user_me["data"]["id"] - -# Make a request to the bookmarks url -url = "https://api.twitter.com/2/users/{}/bookmarks/{}".format( - user_id, bookmarked_tweet_id -) -headers = { - "Authorization": "Bearer {}".format(access), - "User-Agent": "BookmarksSampleCode", -} -response = requests.request("DELETE", url, headers=headers) -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Bookmarks/delete_bookmark.rb b/Manage-Bookmarks/delete_bookmark.rb deleted file mode 100644 index 77b768c..0000000 --- a/Manage-Bookmarks/delete_bookmark.rb +++ /dev/null @@ -1,111 +0,0 @@ -require 'json' -require 'typhoeus' -require 'twitter_oauth2' - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = ENV["CLIENT_ID"] - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = ENV["CLIENT_SECRET"] - - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Replace with a Tweet ID you want to remove a Bookmark of -tweet_id = "1460323737035677698" - -# Start an OAuth 2.0 session with a public client -client = TwitterOAuth2::Client.new( - identifier: "#{client_id}", - redirect_uri: "#{redirect_uri}" -) - -# Start an OAuth 2.0 session with a confidential client -# Remove the comment on the following lines if you are using a confidential client -# client = TwitterOAuth2::Client.new( -# identifier: "#{client_id}", -# secret: "#{client_secret}", -# redirect_uri: "#{redirect_uri}" -# ) - -# Create your authorize url -authorization_url = client.authorization_uri( - scope: [ - :'users.read', - :'tweet.read', - :'bookmark.write', - :'offline.access' - ] -) - -# Set code verifier and state -code_verifier = client.code_verifier -state = client.state - -# Visit the URL to authorize your App to make requests on behalf of a user -print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' -puts authorization_url -`open "#{authorization_url}"` - -print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush - -# Fetch your access token -full_text = gets.chop -new_code = full_text.split("code=") -code = new_code[1] -client.authorization_code = code - -# Your access token -token_response = client.access_token! code_verifier - -# Make a request to the users/me endpoint to get your user ID -def users_me(url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "BookmarksSampleCode", - "Authorization": "Bearer #{token_response}" - }, - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -url = "https://api.twitter.com/2/users/me" -me_response = users_me(url, token_response) - -json_s = JSON.parse(me_response.body) -user_id = json_s["data"]["id"] - -# Make a request to the bookmarks url -bookmarks_url = "https://api.twitter.com/2/users/#{user_id}/bookmarks/#{tweet_id}" - -def bookmarked_tweets(bookmarks_url, token_response) - options = { - method: 'delete', - headers: { - "User-Agent": "BookmarksSampleCode", - "Authorization": "Bearer #{token_response}" - } - } - - request = Typhoeus::Request.new(bookmarks_url, options) - response = request.run - - return response -end - -response = bookmarked_tweets(bookmarks_url, token_response) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Direct-Messages/post_dm_to_conversation.py b/Manage-Direct-Messages/post_dm_to_conversation.py deleted file mode 100644 index f257231..0000000 --- a/Manage-Direct-Messages/post_dm_to_conversation.py +++ /dev/null @@ -1,113 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -#This example is set up to add a DM to a specified conversation by referencing its ID. -POST_DM_URL = "https://api.twitter.com/2/dm_conversations/:dm_conversation_id/messages" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = '' -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- -# These variables indicate the conversation that the message should be added to. A more ready-to-be used example would -# have these passed in from some calling code. -# Provide the ID of the conversation this message should be added to. -dm_conversation_id = "1512210732774948865" -#Set the text of the message to be sent. -text_message = "Hi, I am adding a message to an existing conversation by referencing its ID." -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier. - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge. - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start an OAuth 2.0 session. - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL. - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user. - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request. - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token. - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # The access token. - access = token["access_token"] - - return access - -def add_dm_to_conversation(dm_text, dm_conversation_id): - request_body = {} - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = POST_DM_URL.replace(':dm_conversation_id', str(dm_conversation_id)) - request_body['text'] = dm_text - json_body = json.dumps(request_body) - - #Send DM - response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) - - if response.status_code != 201: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - - return response - -def main(): - response = add_dm_to_conversation(text_message, dm_conversation_id) - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Manage-Direct-Messages/post_group_conversation_dm.py b/Manage-Direct-Messages/post_group_conversation_dm.py deleted file mode 100644 index 0cb0082..0000000 --- a/Manage-Direct-Messages/post_group_conversation_dm.py +++ /dev/null @@ -1,116 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -#This example is set up to create a new group conversation and add a new DM to it. -POST_DM_URL = "https://api.twitter.com/2/dm_conversations" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = '' -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- -# These variables indicate the participants of the new group conversation and the message to add. A more ready-to-be -# used example would have these passed in from some calling code. -#Who is in this group conversation? Reference their User IDs. -participant_ids = ["944480690","906948460078698496"] -#Set the text of the message to be sent. -text_message = "Hi, I am creating a new *group* conversation, and starting it with the this message." -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier. - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge. - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start an OAuth 2.0 session. - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL. - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user. - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request. - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token. - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client. - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # The access token - access = token["access_token"] - - return access - -def create_new_group_conversation_with_dm(dm_text, participant_ids): - request_body = {} - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = POST_DM_URL - request_body['message'] = {} - request_body['message']['text'] = dm_text - request_body['participant_ids'] = participant_ids - request_body['conversation_type'] = "Group" - json_body = json.dumps(request_body) - - #Send DM - response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) - - if response.status_code != 201: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - - return response - -def main(): - response = create_new_group_conversation_with_dm(text_message, participant_ids) - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Manage-Direct-Messages/post_one_to_one_dm.py b/Manage-Direct-Messages/post_one_to_one_dm.py deleted file mode 100644 index 582a43e..0000000 --- a/Manage-Direct-Messages/post_one_to_one_dm.py +++ /dev/null @@ -1,114 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests_oauthlib import OAuth2Session - -#This example is set up to add a new DM to a one-to-one conversation. -POST_DM_URL = "https://api.twitter.com/2/dm_conversations/with/:participant_id/messages" - -#----------------------------------------------------------------------------------------------------------------------- -# These variables need to be updated to the setting that match how your Twitter App is set-up at -# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. -client_id = '' -#This must match *exactly* the redirect URL specified in the Developer Portal. -redirect_uri = "https://www.example.com" -#----------------------------------------------------------------------------------------------------------------------- -# These variables indicate the participant of the one-to-one conversation and the message to add. A more ready-to-be -# used example would have these passed in from some calling code. -#Who is this DM being sent to? Reference their User ID. -participant_id = "944480690" -#Set the text of the message to be sent. -text_message = "Hi, I am DMing you using the v2 DM one-to-one endpoint." -#----------------------------------------------------------------------------------------------------------------------- - -def handle_oauth(): - - # Set the scopes needed to be granted by the authenticating user. - scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] - - # Create a code verifier - code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") - code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - - # Create a code challenge - code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() - code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") - code_challenge = code_challenge.replace("=", "") - - # Start an OAuth 2.0 session - oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - - # Create an authorize URL - auth_url = "https://twitter.com/i/oauth2/authorize" - authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" - ) - - # Visit the URL to authorize your App to make requests on behalf of a user - print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" - ) - print(authorization_url) - - # Paste in your authorize URL to complete the request - authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" - ) - - # Fetch your access token - token_url = "https://api.twitter.com/2/oauth2/token" - - # The following line of code will only work if you are using a type of App that is a public client - auth = False - - token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, - ) - - # Your access token - access = token["access_token"] - - return access - -def post_dm_to_one_to_one_conversation(participant_id): - - request_body = {} - - access = handle_oauth() - - headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "TwitterDevSampleCode", - "X-TFE-Experiment-environment": "staging1", - "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" - } - - request_url = POST_DM_URL.replace(':participant_id', str(participant_id)) - request_body['text'] = text_message - json_body = json.dumps(request_body) - - #Send DM - response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) - - if response.status_code != 201: - print("Request returned an error: {} {}".format(response.status_code, response.text)) - else: - print(f"Response code: {response.status_code}") - - return response - -def main(): - response = post_dm_to_one_to_one_conversation(participant_id) - print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) - -if __name__ == "__main__": - main() diff --git a/Manage-Likes/like_a_tweet.js b/Manage-Likes/like_a_tweet.js deleted file mode 100644 index 638a36a..0000000 --- a/Manage-Likes/like_a_tweet.js +++ /dev/null @@ -1,148 +0,0 @@ -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}); - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticating user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// You can replace Tweet ID given with the Tweet ID you wish to like. -// You can find a Tweet ID by using the Tweet lookup endpoint -const data = { - "tweet_id": "1354143047324299264" -}; - -const endpointURL = `https://api.twitter.com/2/users/${id}/likes`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'POST' - }, token)); - - const req = await got.post(endpointURL, { - json: data, - responseType: 'json', - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2LikeTweetJS", - 'content-type': "application/json", - 'accept': "application/json" - } - }); - if (req.body) { - return req.body; - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Likes/like_a_tweet.py b/Manage-Likes/like_a_tweet.py deleted file mode 100644 index abe8818..0000000 --- a/Manage-Likes/like_a_tweet.py +++ /dev/null @@ -1,77 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace Tweet ID given with the Tweet ID you wish to like. -# You can find a Tweet ID by using the Tweet lookup endpoint -payload = {"tweet_id": "1354143047324299264"} - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.post( - "https://api.twitter.com/2/users/{}/likes".format(id), json=payload -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Likes/like_a_tweet.rb b/Manage-Likes/like_a_tweet.rb deleted file mode 100644 index a07abcd..0000000 --- a/Manage-Likes/like_a_tweet.rb +++ /dev/null @@ -1,86 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" -likes_url = "https://api.twitter.com/2/users/#{id}/likes" - -# You can replace Tweet ID given with the Tweet ID you wish to like. -# You can find a Tweet ID by using the Tweet lookup endpoint -@tweet_id = { "tweet_id": "1354143047324299264" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_like(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2LikeTweetRuby", - "content-type": "application/json" - }, - body: JSON.dump(@tweet_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = user_like(likes_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Likes/unlike_a_tweet.js b/Manage-Likes/unlike_a_tweet.js deleted file mode 100644 index c5ad508..0000000 --- a/Manage-Likes/unlike_a_tweet.js +++ /dev/null @@ -1,145 +0,0 @@ -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}); - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticating user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - - -// You can replace Tweet ID given with the Tweet ID you wish to like. -// You can find a Tweet ID by using the Tweet lookup endpoint -const tweet_id = "1354143047324299264"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/likes/${tweet_id}`; - - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'DELETE' - }, token)); - - const req = await got.delete(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UnlikeTweetJS" - } - }); - - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Likes/unlike_a_tweet.py b/Manage-Likes/unlike_a_tweet.py deleted file mode 100644 index 33151af..0000000 --- a/Manage-Likes/unlike_a_tweet.py +++ /dev/null @@ -1,77 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace Tweet ID given with the Tweet ID you wish to like. -# You can find a Tweet ID by using the Tweet lookup endpoint -tweet_id = "1354143047324299264" - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.delete( - "https://api.twitter.com/2/users/{}/likes/{}".format(id, tweet_id) -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Likes/unlike_a_tweet.rb b/Manage-Likes/unlike_a_tweet.rb deleted file mode 100644 index d1351a2..0000000 --- a/Manage-Likes/unlike_a_tweet.rb +++ /dev/null @@ -1,84 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) - -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace Tweet ID given with the Tweet ID you wish to like. -# You can find a Tweet ID by using the Tweet lookup endpoint -tweet_id = "1354143047324299264" - -# Returns a user object for one or more users specified by the requested usernames -tweet_unlike_url = "https://api.twitter.com/2/users/#{id}/likes/#{tweet_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def tweet_unlike(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2UnlikeTweetRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = tweet_unlike(tweet_unlike_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-Followed-Lists/follow_list.js b/Manage-Lists/Manage-Followed-Lists/follow_list.js deleted file mode 100644 index a4ec8d0..0000000 --- a/Manage-Lists/Manage-Followed-Lists/follow_list.js +++ /dev/null @@ -1,152 +0,0 @@ -// Follow a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to add replace list-id-to-follow with the list id you wish to follow. - -const data = { - list_id: "list-id-to-follow", -}; - -const endpointURL = `https://api.twitter.com/2/users/${id}/followed_lists`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "POST", - }, - token - ) - ); - - const req = await got.post(endpointURL, { - json: data, - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2followListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-Followed-Lists/follow_list.rb b/Manage-Lists/Manage-Followed-Lists/follow_list.rb deleted file mode 100644 index 57c1bed..0000000 --- a/Manage-Lists/Manage-Followed-Lists/follow_list.rb +++ /dev/null @@ -1,85 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -following_url = "https://api.twitter.com/2/users/#{id}/followed_lists" - -# Be sure to add replace list-id-to-follow with the list id you wish to follow. -@list_id = { "list_id": "list-id-to-follow" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def follow_list(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2followListRuby", - "content-type": "application/json" - }, - body: JSON.dump(@list_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = follow_list(following_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-Followed-Lists/unfollow_list.js b/Manage-Lists/Manage-Followed-Lists/unfollow_list.js deleted file mode 100644 index 7138fc9..0000000 --- a/Manage-Lists/Manage-Followed-Lists/unfollow_list.js +++ /dev/null @@ -1,149 +0,0 @@ -// Unfollow a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to replace list-id-to-unfollow with the user id you wish to unfollow. - -const list_id = "list-id-to-unfollow"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/followed_lists/${list_id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "DELETE", - }, - token - ) - ); - - const req = await got.delete(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2unfollowListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-Followed-Lists/unfollow_list.rb b/Manage-Lists/Manage-Followed-Lists/unfollow_list.rb deleted file mode 100644 index 2d3535f..0000000 --- a/Manage-Lists/Manage-Followed-Lists/unfollow_list.rb +++ /dev/null @@ -1,81 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-unfollow with the user id of the user you wish to unfollow. -list_id = "list-id-to-unfollow" - -# Returns a user object for one or more users specified by the requested usernames -unfollow_url = "https://api.twitter.com/2/users/#{id}/followed_lists/#{list_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def unfollow_list(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2unfollowListRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = unfollow_list(unfollow_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-List-Members/add_member.js b/Manage-Lists/Manage-List-Members/add_member.js deleted file mode 100644 index 37458c3..0000000 --- a/Manage-Lists/Manage-List-Members/add_member.js +++ /dev/null @@ -1,151 +0,0 @@ -// Add member to a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-list-id with your own list ID or one of an authenticated user -const id = "your-list-id"; - -// Be sure to replace user-id-to-add with the user id you wish to add. -// You can find a user ID by using the user lookup endpoint -const data = { - user_id: "user-id-to-add", -}; - -const endpointURL = `https://api.twitter.com/2/lists/${id}/members`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "POST", - }, - token - ) - ); - - const req = await got.post(endpointURL, { - json: data, - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2addMemberJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-List-Members/add_member.rb b/Manage-Lists/Manage-List-Members/add_member.rb deleted file mode 100644 index 6d6668a..0000000 --- a/Manage-Lists/Manage-List-Members/add_member.rb +++ /dev/null @@ -1,84 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-list-id with your own list ID or one of an authenticating user -id = "your-list-id" - -member_url = "https://api.twitter.com/2/lists/#{id}/members" - -# Be sure to replace user-id-to-add with the user id you wish to add. -@user_id = { "user_id": "user-id-to-add" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def add_member(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2addMemberRuby", - "content-type": "application/json" - }, - body: JSON.dump(@user_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = add_member(member_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-List-Members/remove_member.js b/Manage-Lists/Manage-List-Members/remove_member.js deleted file mode 100644 index 2ec42e2..0000000 --- a/Manage-Lists/Manage-List-Members/remove_member.js +++ /dev/null @@ -1,149 +0,0 @@ -// Remove member from a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-list-id with your own list ID or one of an authenticated user -const id = "your-list-id"; - -// Be sure to replace user-id-to-remove with the user id you wish to remove. -// You can find a user ID by using the user lookup endpoint - -const user_id = "user-id-to-remove"; - -const endpointURL = `https://api.twitter.com/2/lists/${id}/members/${user_id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "DELETE", - }, - token - ) - ); - - const req = await got.delete(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2removeMemberJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-List-Members/remove_member.rb b/Manage-Lists/Manage-List-Members/remove_member.rb deleted file mode 100644 index a4fa4c6..0000000 --- a/Manage-Lists/Manage-List-Members/remove_member.rb +++ /dev/null @@ -1,83 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-list-id with your own list ID or one of an authenticating user -id = "your-list-id" - -# Be sure to replace user-id-to-remove with the user id you wish to remove. -user_id = "user-id-to-remove" - -member_url = "https://api.twitter.com/2/lists/#{id}/members/#{user_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def remove_member(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2removeMemberRuby", - "content-type": "application/json" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = remove_member(member_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-Pinned-Lists/pin_list.js b/Manage-Lists/Manage-Pinned-Lists/pin_list.js deleted file mode 100644 index 8430e61..0000000 --- a/Manage-Lists/Manage-Pinned-Lists/pin_list.js +++ /dev/null @@ -1,152 +0,0 @@ -// Pin a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to add replace list-id-to-pin with the list id you wish to pin. - -const data = { - list_id: "list-id-to-pin", -}; - -const endpointURL = `https://api.twitter.com/2/users/${id}/pinned_lists`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "POST", - }, - token - ) - ); - - const req = await got.post(endpointURL, { - json: data, - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2pinListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-Pinned-Lists/pin_list.py b/Manage-Lists/Manage-Pinned-Lists/pin_list.py deleted file mode 100644 index 127b2c0..0000000 --- a/Manage-Lists/Manage-Pinned-Lists/pin_list.py +++ /dev/null @@ -1,77 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-pin with the list id you wish to pin. -payload = {"list_id": "list-id-to-pin"} - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.post( - "https://api.twitter.com/2/users/{}/pinned_lists".format(id), json=payload -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Lists/Manage-Pinned-Lists/pin_list.rb b/Manage-Lists/Manage-Pinned-Lists/pin_list.rb deleted file mode 100644 index 9bf5617..0000000 --- a/Manage-Lists/Manage-Pinned-Lists/pin_list.rb +++ /dev/null @@ -1,85 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -pin_url = "https://api.twitter.com/2/users/#{id}/pinned_lists" - -# Be sure to add replace list-id-to-pin with the list id you wish to pin. -@list_id = { "list_id": "list-id-to-pin" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def pin_list(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2pinListRuby", - "content-type": "application/json" - }, - body: JSON.dump(@list_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = pin_list(pin_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/Manage-Pinned-Lists/unpin_list.js b/Manage-Lists/Manage-Pinned-Lists/unpin_list.js deleted file mode 100644 index a7db4ca..0000000 --- a/Manage-Lists/Manage-Pinned-Lists/unpin_list.js +++ /dev/null @@ -1,149 +0,0 @@ -// Unpin a list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to replace list-id-to-unpin with the user id you wish to unpin. - -const list_id = "list-id-to-unpin"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/pinned_lists/${list_id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "DELETE", - }, - token - ) - ); - - const req = await got.delete(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2unpinListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/Manage-Pinned-Lists/unpin_list.rb b/Manage-Lists/Manage-Pinned-Lists/unpin_list.rb deleted file mode 100644 index f800997..0000000 --- a/Manage-Lists/Manage-Pinned-Lists/unpin_list.rb +++ /dev/null @@ -1,81 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-unpin with the user id of the user you wish to unpin. -list_id = "list-id-to-unpin" - -# Returns a user object for one or more users specified by the requested usernames -unpin_url = "https://api.twitter.com/2/users/#{id}/pinned_lists/#{list_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def unpin_list(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2unpinListRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = unpin_list(unpin_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/create_a_list.js b/Manage-Lists/create_a_list.js deleted file mode 100644 index d4ac6e1..0000000 --- a/Manage-Lists/create_a_list.js +++ /dev/null @@ -1,150 +0,0 @@ -// Create a new list using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to add replace name-of-list with the name you wish to call the list. -// description and private keys are optional -const data = { - name: "name-of-list", - description: "description-of-list", - private: false, -}; - -const endpointURL = `https://api.twitter.com/2/lists`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "POST", - }, - token - ) - ); - - const req = await got.post(endpointURL, { - json: data, - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2createListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/create_a_list.rb b/Manage-Lists/create_a_list.rb deleted file mode 100644 index d61822f..0000000 --- a/Manage-Lists/create_a_list.rb +++ /dev/null @@ -1,86 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - - -create_list_url = "https://api.twitter.com/2/lists" - -# Be sure to add replace name-of-list with the name you wish to call the list. -# description and private keys are optional -@json_payload = { "name": "name-of-list", -"description": "description-of-list", -"private": false} - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def create_list(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2createListRuby", - "content-type": "application/json" - }, - body: JSON.dump(@json_payload) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = create_list(create_list_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/delete_a_list.js b/Manage-Lists/delete_a_list.js deleted file mode 100644 index 918a625..0000000 --- a/Manage-Lists/delete_a_list.js +++ /dev/null @@ -1,144 +0,0 @@ -// Delete an existing list the authenticated user owns - using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to add replace the your-list-id with the id of the list you wish to delete. -const target_list_id = "your-list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${target_list_id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "DELETE", - }, - token - ) - ); - - const req = await got.delete(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2deleteListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/delete_a_list.rb b/Manage-Lists/delete_a_list.rb deleted file mode 100644 index 3ae36dc..0000000 --- a/Manage-Lists/delete_a_list.rb +++ /dev/null @@ -1,83 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-list-id with the id of the list you wish to delete. The authenticated user must own the list in order to delete - -id = "your-list-id" - -delete_list_url = "https://api.twitter.com/2/lists/#{id}" - - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def delete_list(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2deleteListRuby", - "content-type": "application/json" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = delete_list(delete_list_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Lists/update_a_list.js b/Manage-Lists/update_a_list.js deleted file mode 100644 index 58196f6..0000000 --- a/Manage-Lists/update_a_list.js +++ /dev/null @@ -1,153 +0,0 @@ -// Update the metadata of an existing list the authenticated user owns - using PIN-based OAuth to authorize the user -// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to add replace update-name-of-list with the name you wish to call the list. -// name, description and private are all optional -const data = { - name: "update-name-of-list", - description: "update-description-of-list", - private: false, -}; - -// Be sure to add replace the your-list-id with the list id of the list you wish to update. -const target_list_id = "your-list-id"; - -const endpointURL = `https://api.twitter.com/2/lists/${target_list_id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "PUT", - }, - token - ) - ); - - const req = await got.put(endpointURL, { - json: data, - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2updateListJS", - "content-type": "application/json", - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Lists/update_a_list.rb b/Manage-Lists/update_a_list.rb deleted file mode 100644 index 9d5d97b..0000000 --- a/Manage-Lists/update_a_list.rb +++ /dev/null @@ -1,89 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to add replace update-name-of-list with the name you wish to call the list. -# name, description and private are all optional -@json_payload = { "name": "update-name-of-list-ruby", - "description": "update-description-of-list", - "private": false} - -# Be sure to replace your-list-id with the id of the list you wish to update. The authenticated user must own the list in order to update -id = "your-list-id" - -update_list_url = "https://api.twitter.com/2/lists/#{id}" - - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def update_list(url, oauth_params) - options = { - :method => :put, - headers: { - "User-Agent": "v2updateListRuby", - "content-type": "application/json" - }, - body: JSON.dump(@json_payload) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = update_list(update_list_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Mutes/mute_a_user.js b/Manage-Mutes/mute_a_user.js deleted file mode 100644 index b912920..0000000 --- a/Manage-Mutes/mute_a_user.js +++ /dev/null @@ -1,150 +0,0 @@ -// mute a user, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// Be sure to add replace id-to-mute with the user id you wish to mute. -// You can find a user ID by using the user lookup endpoint -const data = { - "target_user_id": "id-to-mute" -} - -const endpointURL = `https://api.twitter.com/2/users/${id}/muting`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'POST' - }, token)); - - const req = await got.post(endpointURL, { - json: data, - responseType: 'json', - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2muteUserJS", - 'content-type': "application/json", - 'accept': "application/json" - } - }); - if (req.body) { - return req.body; - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Mutes/mute_a_user.rb b/Manage-Mutes/mute_a_user.rb deleted file mode 100644 index 5ea974d..0000000 --- a/Manage-Mutes/mute_a_user.rb +++ /dev/null @@ -1,85 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" -muting_url = "https://api.twitter.com/2/users/#{id}/muting" - -# Be sure to add replace id-to-mute with the id of the user you wish to mute. -# You can find a user ID by using the user lookup endpoint -@target_user_id = { "target_user_id": "id-to-mute" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_mute(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2muteUserRuby", - "content-type": "application/json" - }, - body: JSON.dump(@target_user_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = user_mute(muting_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Mutes/unmute_a_user.js b/Manage-Mutes/unmute_a_user.js deleted file mode 100644 index fa0785f..0000000 --- a/Manage-Mutes/unmute_a_user.js +++ /dev/null @@ -1,145 +0,0 @@ -// Unmute a user, using user authentication -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const source_user_id = "your-user-id"; - - -// Be sure to add replace the id-to-unmute with the user id of the you wish to unmute. -// You can find a user ID by using the user lookup endpoint -const target_user_id = "id-to-unmute" - -const endpointURL = `https://api.twitter.com/2/users/${source_user_id}/muting/${target_user_id}`; - - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - : { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - : { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'DELETE' - }, token)); - - const req = await got.post(endpointURL, { - : { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UnmuteUserJS" - } - }); - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Mutes/unmute_a_user.py b/Manage-Mutes/unmute_a_user.py deleted file mode 100644 index 518072a..0000000 --- a/Manage-Mutes/unmute_a_user.py +++ /dev/null @@ -1,79 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - - -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -source_user_id = "your-user-id" - -# Be sure to add replace id-to-unmute with the id of the user you wish to unmute. -# You can find a user ID by using the user lookup endpoint -target_user_id = "id-to-unmute" - - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.delete( - "https://api.twitter.com/2/users/{}/muting/{}".format(id, target_user_id) -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Mutes/unmute_a_user.rb b/Manage-Mutes/unmute_a_user.rb deleted file mode 100644 index 7fac9d9..0000000 --- a/Manage-Mutes/unmute_a_user.rb +++ /dev/null @@ -1,82 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -source_user_id = "your-user-id" - -# Be sure to add replace id-to-unmute with the user id of the user you wish to unmute. -# You can find a user ID by using the user lookup endpoint -target_user_id = "id-to-unmute" - -# Returns a user object for one or more users specified by the requested usernames -user_unmute_url = "https://api.twitter.com/2/users/#{source_user_id}/muting/#{target_user_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_unmute(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2UnmuteUserRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = user_unmute(user_unmute_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Retweets/.#bearer_test.py b/Manage-Retweets/.#bearer_test.py deleted file mode 120000 index cf1e1e2..0000000 --- a/Manage-Retweets/.#bearer_test.py +++ /dev/null @@ -1 +0,0 @@ -jgarson@tw-mbp-jgarson.9884 \ No newline at end of file diff --git a/Manage-Retweets/retweet_a_tweet.js b/Manage-Retweets/retweet_a_tweet.js deleted file mode 100644 index b4ede7f..0000000 --- a/Manage-Retweets/retweet_a_tweet.js +++ /dev/null @@ -1,148 +0,0 @@ -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - -// You can replace the given Tweet ID with your the Tweet ID you want to Retweet -// You can find a Tweet ID by using the Tweet lookup endpoint -const data = { - "tweet_id": "1412865600439738368" -} - -const endpointURL = `https://api.twitter.com/2/users/${id}/retweets`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'POST' - }, token)); - - const req = await got.post(endpointURL, { - json: data, - responseType: 'json', - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "vsRetweetTweetJS", - 'content-type': "application/json", - 'accept': "application/json" - } - }); - if (req.body) { - return req.body; - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Retweets/retweet_a_tweet.py b/Manage-Retweets/retweet_a_tweet.py deleted file mode 100644 index 449f386..0000000 --- a/Manage-Retweets/retweet_a_tweet.py +++ /dev/null @@ -1,78 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace the given Tweet ID with your the Tweet ID you want to Retweet -# You can find a Tweet ID by using the Tweet lookup endpoint -payload = {"tweet_id": "1412865600439738368"} - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.post( - "https://api.twitter.com/2/users/{}/retweets".format(id), json=payload -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Retweets/retweet_a_tweet.rb b/Manage-Retweets/retweet_a_tweet.rb deleted file mode 100644 index a707930..0000000 --- a/Manage-Retweets/retweet_a_tweet.rb +++ /dev/null @@ -1,86 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to add replace id of the user you wish to retweet on behalf of. -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" -retweets_url = "https://api.twitter.com/2/users/#{id}/retweets" - -# Be sure to replace tweet-id with your the Tweet ID you want to retweet -# You can find a Tweet ID by using the Tweet lookup endpoint -@tweet_id = { "tweet_id": "1412865600439738368" } - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_retweet(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2retweetUserRuby", - "content-type": "application/json" - }, - body: JSON.dump(@tweet_id) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = user_retweet(retweets_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Retweets/undo_a_retweet.js b/Manage-Retweets/undo_a_retweet.js deleted file mode 100644 index 0b70840..0000000 --- a/Manage-Retweets/undo_a_retweet.js +++ /dev/null @@ -1,145 +0,0 @@ -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); - -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}); - - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - - -// Be sure to replace your-user-id with your own user ID or one of an authenticating user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; - - -// You can replace the given Tweet ID with your the Tweet ID you want to Retweet -// You can find a Tweet ID by using the Tweet lookup endpoint -const source_tweet_id = "1354143047324299264"; - -const endpointURL = `https://api.twitter.com/2/users/${id}/retweets/${source_tweet_id}`; - - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'DELETE' - }, token)); - - const req = await got.delete(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UndoRetweetTweetJS" - } - }); - - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Retweets/undo_a_retweet.py b/Manage-Retweets/undo_a_retweet.py deleted file mode 100644 index 7c427c6..0000000 --- a/Manage-Retweets/undo_a_retweet.py +++ /dev/null @@ -1,79 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - - -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace the given Tweet ID with your the Tweet ID you want to Retweet -# You can find a Tweet ID by using the Tweet lookup endpoint -source_tweet_id = "1412865600439738368" - - -# Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -# Making the request -response = oauth.delete( - "https://api.twitter.com/2/users/{}/retweets/{}".format(id, source_tweet_id) -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) - -# Saving the response as JSON -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Retweets/undo_a_retweet.rb b/Manage-Retweets/undo_a_retweet.rb deleted file mode 100644 index 6358152..0000000 --- a/Manage-Retweets/undo_a_retweet.rb +++ /dev/null @@ -1,84 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) - -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# You can replace the given Tweet ID with your the Tweet ID you want to Retweet -# You can find a Tweet ID by using the Tweet lookup endpoint -source_tweet_id = "1412865600439738368" - -# Returns a user object for one or more users specified by the requested usernames -user_unretweet_url = "https://api.twitter.com/2/users/#{id}/retweets/#{source_tweet_id}" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def user_unretweet(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2UndoRetweetUserRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = user_unretweet(user_unretweet_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Tweets/create_tweet.rb b/Manage-Tweets/create_tweet.rb deleted file mode 100644 index 4fdb071..0000000 --- a/Manage-Tweets/create_tweet.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - - -create_tweet_url = "https://api.twitter.com/2/tweets" - -# Be sure to add replace the text of the with the text you wish to Tweet. -# You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. -@json_payload = {"text": "Hello world!"} - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def create_tweet(url, oauth_params) - options = { - :method => :post, - headers: { - "User-Agent": "v2CreateTweetRuby", - "content-type": "application/json" - }, - body: JSON.dump(@json_payload) - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = create_tweet(create_tweet_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Manage-Tweets/delete_tweet.js b/Manage-Tweets/delete_tweet.js deleted file mode 100644 index a62a913..0000000 --- a/Manage-Tweets/delete_tweet.js +++ /dev/null @@ -1,142 +0,0 @@ -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-tweet-id with the id of the Tweet you wish to delete. -const id = "your-tweet-id"; - -const endpointURL = `https://api.twitter.com/2/tweets/${id}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "DELETE", - }, - token - ) - ); - - const req = await got.delete(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2DeleteTweetJS", - "content-type": "application/json" - accept: "application/json", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Manage-Tweets/delete_tweet.rb b/Manage-Tweets/delete_tweet.rb deleted file mode 100644 index 294407e..0000000 --- a/Manage-Tweets/delete_tweet.rb +++ /dev/null @@ -1,79 +0,0 @@ -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-tweet-id with the id of the Tweet you wish to delete. -id = "your-tweet-id" - -delete_tweet_url = "https://api.twitter.com/2/tweets/#{id}" - - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def delete_tweet(url, oauth_params) - options = { - :method => :delete, - headers: { - "User-Agent": "v2DeleteTweetRuby", - "content-type": "application/json" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = delete_tweet(delete_tweet_url, oauth_params) diff --git a/Media Upload/media_upload_v2.py b/Media Upload/media_upload_v2.py deleted file mode 100644 index 0b28df2..0000000 --- a/Media Upload/media_upload_v2.py +++ /dev/null @@ -1,229 +0,0 @@ -import os -import sys -import base64 -import hashlib -import re -import time -import requests -from requests_oauthlib import OAuth2Session - -MEDIA_ENDPOINT_URL = 'https://api.x.com/2/media/upload' -POST_TO_X_URL = 'https://api.x.com/2/tweets' - -# Replace with path to file -VIDEO_FILENAME = 'REPLACE_ME' - -# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = os.environ.get("CLIENT_ID") - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = os.environ.get("CLIENT_SECRET") - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Set the scopes -scopes = ["media.write", "users.read", "tweet.read", "tweet.write", "offline.access"] - -# Create a code verifier -code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") -code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - -# Create a code challenge -code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() -code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") -code_challenge = code_challenge.replace("=", "") - -# Start and OAuth 2.0 session -oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - -# Create an authorize URL -auth_url = "https://x.com/i/oauth2/authorize" -authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" -) - -# Visit the URL to authorize your App to make requests on behalf of a user -print( - "Visit the following URL to authorize your App on behalf of your X handle in a browser:" -) -print(authorization_url) - -# Paste in your authorize URL to complete the request -authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" -) - -# Fetch your access token -token_url = "https://api.x.com/2/oauth2/token" - -# The following line of code will only work if you are using a type of App that is a public client -auth = False - -# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. - -# Please remove the comment on the following line if you are using a type of App that is a confidential client -# auth = HTTPBasicAuth(client_id, client_secret) - -token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, -) - -# Your access token -access = token["access_token"] - -headers = { - "Authorization": "Bearer {}".format(access), - "Content-Type": "application/json", - "User-Agent": "MediaUploadSampleCode", -} - - -class VideoPost(object): - - def __init__(self, file_name): - # Defines video Post properties - self.video_filename = file_name - self.total_bytes = os.path.getsize(self.video_filename) - self.media_id = None - self.processing_info = None - - def upload_init(self): - # Initializes Upload - print('INIT') - - request_data = { - 'command': 'INIT', - 'media_type': 'video/mp4', - 'total_bytes': self.total_bytes, - 'media_category': 'tweet_video' - } - - req = requests.post(url=MEDIA_ENDPOINT_URL, params=request_data, headers=headers) - print(req.status_code) - print(req.text) - media_id = req.json()['data']['id'] - - self.media_id = media_id - - print('Media ID: %s' % str(media_id)) - - def upload_append(self): - segment_id = 0 - bytes_sent = 0 - with open(self.video_filename, 'rb') as file: - while bytes_sent < self.total_bytes: - chunk = file.read(4 * 1024 * 1024) # 4MB chunk size - - print('APPEND') - - files = {'media': ('chunk', chunk, 'application/octet-stream')} - - data = { - 'command': 'APPEND', - 'media_id': self.media_id, - 'segment_index': segment_id - } - - headers = { - "Authorization": f"Bearer {access}", - "User-Agent": "MediaUploadSampleCode", - } - - req = requests.post(url=MEDIA_ENDPOINT_URL, data=data, files=files, headers=headers) - - if req.status_code < 200 or req.status_code > 299: - print(req.status_code) - print(req.text) - sys.exit(0) - - segment_id += 1 - bytes_sent = file.tell() - - print(f'{bytes_sent} of {self.total_bytes} bytes uploaded') - - print('Upload chunks complete.') - - def upload_finalize(self): - - # Finalizes uploads and starts video processing - print('FINALIZE') - - request_data = { - 'command': 'FINALIZE', - 'media_id': self.media_id - } - - req = requests.post(url=MEDIA_ENDPOINT_URL, params=request_data, headers=headers) - - print(req.json()) - - self.processing_info = req.json()['data'].get('processing_info', None) - self.check_status() - - def check_status(self): - # Checks video processing status - if self.processing_info is None: - return - - state = self.processing_info['state'] - - print('Media processing status is %s ' % state) - - if state == u'succeeded': - return - - if state == u'failed': - sys.exit(0) - - check_after_secs = self.processing_info['check_after_secs'] - - print('Checking after %s seconds' % str(check_after_secs)) - time.sleep(check_after_secs) - - print('STATUS') - - request_params = { - 'command': 'STATUS', - 'media_id': self.media_id - } - - req = requests.get(url=MEDIA_ENDPOINT_URL, params=request_params, headers=headers) - - self.processing_info = req.json()['data'].get('processing_info', None) - self.check_status() - - def post(self): - - # Publishes Post with attached video - payload = { - 'text': 'I just uploaded a video with the media upload v2 @XDevelopers API.', - 'media': { - 'media_ids': [self.media_id] - } - } - - req = requests.post(url=POST_TO_X_URL, json=payload, headers=headers) - - print(req.json()) - - -if __name__ == '__main__': - videoPost = VideoPost(VIDEO_FILENAME) - videoPost.upload_init() - videoPost.upload_append() - videoPost.upload_finalize() - videoPost.post() diff --git a/Mutes-Lookup/lookup_mutes.js b/Mutes-Lookup/lookup_mutes.js deleted file mode 100644 index 5177153..0000000 --- a/Mutes-Lookup/lookup_mutes.js +++ /dev/null @@ -1,142 +0,0 @@ -// Retrieve accounts muted by authenticated user -// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; -const endpointURL = `https://api.twitter.com/2/users/${id}/muting`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "GET", - }, - token - ) - ); - - const req = await got.get(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2MutesLookupJS", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Mutes-Lookup/lookup_mutes.py b/Mutes-Lookup/lookup_mutes.py deleted file mode 100644 index 89f313c..0000000 --- a/Mutes-Lookup/lookup_mutes.py +++ /dev/null @@ -1,79 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -params = {"user.fields": "created_at,description"} - - -# User fields are adjustable, options include: -# created_at, description, entities, id, location, name, -# pinned_tweet_id, profile_image_url, protected, -# public_metrics, url, username, verified, and withheld - -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -response = oauth.get( - "https://api.twitter.com/2/users/{}/muting".format(id),params=params -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) \ No newline at end of file diff --git a/Mutes-Lookup/lookup_mutes.rb b/Mutes-Lookup/lookup_mutes.rb deleted file mode 100644 index 0c83fdd..0000000 --- a/Mutes-Lookup/lookup_mutes.rb +++ /dev/null @@ -1,81 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a Mutes lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -muting_url = "https://api.twitter.com/2/users/#{id}/muting" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def users_muted(url, oauth_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2MutesLookupRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - - -response = users_muted(muting_url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) \ No newline at end of file diff --git a/Quote-Tweets/QuoteTweetsDemo.java b/Quote-Tweets/QuoteTweetsDemo.java deleted file mode 100644 index e83a971..0000000 --- a/Quote-Tweets/QuoteTweetsDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 Quote Tweets endpoint - * */ -public class QuoteTweetsDemo { - - // To set your environment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace with Tweet ID below - String response = getTweets(20, bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 Quote Tweets endpoint by Tweet ID - * */ - private static String getTweets(int tweetId, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(String.format("https://api.twitter.com/2/tweets/%s/quote_tweets", tweetId)); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} diff --git a/Quote-Tweets/quote_tweets.js b/Quote-Tweets/quote_tweets.js deleted file mode 100644 index 5b66272..0000000 --- a/Quote-Tweets/quote_tweets.js +++ /dev/null @@ -1,74 +0,0 @@ -// Get Quote Tweets by Tweet ID -// https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets-lookup/quick-start - -const needle = require('needle'); - -const tweetId = 20; -const url = `https://api.twitter.com/2/tweets/${tweetId}/quote_tweets`; - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const bearerToken = process.env.BEARER_TOKEN; - -// this is the ID for @TwitterDev -const getQuoteTweets = async () => { - let quoteTweets = []; - let params = { - "max_results": 100, - "tweet.fields": "created_at" - } - - const options = { - headers: { - "User-Agent": "v2QuoteTweetsJS", - "authorization": `Bearer ${bearerToken}` - } - } - - let hasNextPage = true; - let nextToken = null; - console.log("Retrieving quote Tweets..."); - while (hasNextPage) { - let resp = await getPage(params, options, nextToken); - if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { - if (resp.data) { - quoteTweets.push.apply(quoteTweets, resp.data); - } - if (resp.meta.next_token) { - nextToken = resp.meta.next_token; - } else { - hasNextPage = false; - } - } else { - hasNextPage = false; - } - } - - console.dir(quoteTweets, { - depth: null - }); - - console.log(`Got ${quoteTweets.length} quote Tweets for Tweet ID ${tweetId}!`); - -} - -const getPage = async (params, options, nextToken) => { - if (nextToken) { - params.pagination_token = nextToken; - } - - try { - const resp = await needle('get', url, params, options); - - if (resp.statusCode != 200) { - console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); - return; - } - return resp.body; - } catch (err) { - throw new Error(`Request failed: ${err}`); - } -} - -getQuoteTweets(); diff --git a/Quote-Tweets/quote_tweets.py b/Quote-Tweets/quote_tweets.py deleted file mode 100644 index 509b656..0000000 --- a/Quote-Tweets/quote_tweets.py +++ /dev/null @@ -1,58 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' - - -def auth(): - return os.environ.get("BEARER_TOKEN") - - -def create_url(): - # Replace with Tweet ID below - tweet_id = 20 - return "https://api.twitter.com/2/tweets/{}/quote_tweets".format(tweet_id) - - -def get_params(): - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - return {"tweet.fields": "created_at"} - - -def create_headers(bearer_token): - headers = {"Authorization": "Bearer {}".format(bearer_token)} - return headers - - -def connect_to_endpoint(url, headers, params): - response = requests.request("GET", url, headers=headers, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - bearer_token = auth() - url = create_url() - headers = create_headers(bearer_token) - params = get_params() - json_response = connect_to_endpoint(url, headers, params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() - \ No newline at end of file diff --git a/Quote-Tweets/quote_tweets.rb b/Quote-Tweets/quote_tweets.rb deleted file mode 100644 index 8bb5d2b..0000000 --- a/Quote-Tweets/quote_tweets.rb +++ /dev/null @@ -1,44 +0,0 @@ -# This script uses your bearer token to authenticate and make a request to the Quote Tweets endpoint. -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Quote Tweets endpoint. -endpoint_url = "https://api.twitter.com/2/tweets/:id/quote_tweets" - -# Specify the Tweet ID for this request. -id = 20 - -# Add or remove parameters below to adjust the query and response fields within the payload -# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ -query_params = { - "max_results" => 100, - "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", - "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", - "user.fields" => "description" -} - -def get_quote_tweets(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent" => "v2RubyExampleCode", - "Authorization" => "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -endpoint_url = endpoint_url.gsub(':id',id.to_s()) - -response = get_quote_tweets(endpoint_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/README.md b/README.md index 8da353e..c7dbd72 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,128 @@ -# Twitter API v2 sample code [![v2](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.twitter.com/en/docs/twitter-api) +# X API v2 Sample Code -Sample code for the Twitter API v2 endpoints. -Individual API features have folders where you can find examples of usage in several coding languages (Java, Node.js, Python, R, and Ruby). +[![X API v2](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.x.com/en/docs/twitter-api) -* [Twitter API Documentation](https://developer.twitter.com/en/docs/twitter-api/getting-started/about-twitter-api) +Working code samples for the **X (formerly Twitter) API v2** in Python, JavaScript, Ruby, and Java. -## Prerequisites +## 📁 Repository Structure -* Twitter API Essential Access ([sign up here](https://t.co/signup)) -* A Project and an App created [in the dashboard](https://developer.twitter.com/en/portal/dashboard) - -## Using the code samples - -In order to run the samples in this repository you will need to set up some environment variables. You can find your credentials and bearer token in the App inside of your Project in the [dashboard of the developer portal](https://developer.twitter.com/en/portal/projects-and-apps). - -For OAuth 1.0a samples, you will need to export your consumer key and secret in your terminal. Be sure to replace `` and `` with your own credentials without the `< >`. - -```bash -export CONSUMER_KEY='' -export CONSUMER_SECRET='' ``` - -For samples which use bearer token authentication, you will need to export the bearer token. Be sure to replace `` with your own bearer token without the `< >`. - -```bash -export BEARER_TOKEN='' +├── python/ # Python examples (most complete) +├── javascript/ # JavaScript (Node.js) examples +├── ruby/ # Ruby examples +├── java/ # Java examples +├── llms.txt # LLM-friendly documentation +└── api-index.json # Machine-readable endpoint catalog ``` -## Language-specific requirements +## 🚀 Quick Start -### Java environment set up +### 1. Get API Credentials -If you use Homebrew, you can install a Java runtime using: +Sign up at the [X Developer Portal](https://developer.x.com/en/portal/dashboard) and create a project/app. -```bash -brew cask install java -``` +### 2. Set Environment Variables -You will also need to download the relevant JAR files referenced in the individual samples in order to build and run the code. If you use an IDE, it may be able to do this automatically for you. +```bash +# For app-only authentication (read-only endpoints) +export BEARER_TOKEN='your_bearer_token' -### JavaScript (Node.js) environment set up +# For user context authentication (actions on behalf of users) +export CONSUMER_KEY='your_consumer_key' +export CONSUMER_SECRET='your_consumer_secret' +``` -You will need to have Node.js installed to run this code. All Node.js examples use `needle` as the HTTP client, which needs to be npm installed. For OAuth with user context requests, you'll need to install the `got` and `oauth-1.0a` packages. +### 3. Choose Your Language -```bash -npm install needle -npm install got -npm install oauth-1.0a -``` +| Language | Setup | Run Example | +|----------|-------|-------------| +| **Python** | `pip install -r python/requirements.txt` | `python python/posts/search_recent.py` | +| **JavaScript** | `cd javascript && npm install` | `node javascript/posts/search_recent.js` | +| **Ruby** | `gem install typhoeus` | `ruby ruby/posts/search_recent.rb` | +| **Java** | Add dependencies (see java/README.md) | `javac && java SearchRecent` | -### Python environment set up +## 📚 Available Examples -You will need to have Python 3 installed to run this code. The Python samples use `requests==2.24.0` which uses `requests-oauthlib==1.3.0`. +### Posts (formerly Tweets) -(Optionally) It is common and recommended not to install required package globally, but locally under project subfolder using `venv`: +| Operation | Python | JavaScript | Ruby | Java | +|-----------|--------|------------|------|------| +| Create Post | ✅ | ✅ | | | +| Delete Post | ✅ | ✅ | | | +| Lookup Posts | ✅ | ✅ | ✅ | | +| Search Recent | ✅ | ✅ | ✅ | ✅ | +| Search Full Archive | ✅ | | | | +| Post Counts | ✅ | | | | +| Quote Posts | ✅ | | | | +| Repost | ✅ | | | | +| Like/Unlike | ✅ | | | | -```bash -python3 -m venv venv -source venv/bin/activate -``` +### Users -You can install these packages as follows: +| Operation | Python | JavaScript | Ruby | Java | +|-----------|--------|------------|------|------| +| Lookup Users | ✅ | ✅ | ✅ | ✅ | +| Get Me | ✅ | | | | +| Followers | ✅ | ✅ | ✅ | | +| Following | ✅ | | | | +| Block/Unblock | ✅ | | | | +| Mute/Unmute | ✅ | | | | -```bash -pip install requests -pip install requests-oauthlib -``` +### Timelines -### Ruby environment set up +| Operation | Python | JavaScript | Ruby | +|-----------|--------|------------|------| +| User Posts | ✅ | ✅ | ✅ | +| User Mentions | ✅ | | | +| Home Timeline | ✅ | | | -You will need to have Ruby (recommended: >= 2.0.0) installed in order to run the code. The Ruby examples use `typhoeus` as the HTTP client, which needs to be gem installed. For OAuth with user context requests, you'll also need to install the `oauth` gem (see below). +### Streams -```bash -gem install typhoeus -gem install oauth -``` +| Operation | Python | JavaScript | +|-----------|--------|------------| +| Filtered Stream | ✅ | ✅ | +| Sampled Stream | ✅ | | -## Additional resources +### Other -We maintain a [Postman](https://getpostman.com) Collection which you can use for exercising individual API endpoints. +| Category | Python | JavaScript | Ruby | +|----------|--------|------------|------| +| Bookmarks | ✅ | | | +| Spaces | ✅ | ✅ | | +| Lists | ✅ | ✅ | ✅ | +| Direct Messages | ✅ | | | +| Media Upload | ✅ | | | +| Compliance | ✅ | | | +| Usage Stats | ✅ | | | -* [Using Postman with the Twitter API](https://developer.twitter.com/en/docs/tutorials/postman-getting-started) -* [Twitter API v2 on the Postman website](https://t.co/twitter-api-postman) +## 🔐 Authentication Types -## Support +| Type | Use Case | Required Env Vars | +|------|----------|-------------------| +| **Bearer Token** | Read-only endpoints (search, lookup) | `BEARER_TOKEN` | +| **OAuth 1.0a** | User actions (post, like, follow) | `CONSUMER_KEY`, `CONSUMER_SECRET` | +| **OAuth 2.0 PKCE** | Newer endpoints (bookmarks) | OAuth flow required | -* For general questions related to the API and features, please use the v2 section of our [developer community forums](https://twittercommunity.com/c/twitter-api/twitter-api-v2/65). +## 🔗 Resources -* If there's an bug or issue with the sample code itself, please create a [new issue](https://github.com/twitterdev/Twitter-API-v2-sample-code/issues) here on GitHub. +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [Developer Portal](https://developer.x.com/en/portal/dashboard) +- [API Reference Index](https://developer.x.com/en/docs/api-reference-index) +- [Postman Collection](https://t.co/twitter-api-postman) -## Contributing +## 🤖 For LLMs -We welcome pull requests that add meaningful additions to these code samples, particularly for languages that are not yet represented here. +This repository includes: +- **`llms.txt`** - Comprehensive context file for AI assistants +- **`api-index.json`** - Machine-readable endpoint catalog -We feel that a welcoming community is important and we ask that you follow Twitter's [Open Source Code of Conduct](https://github.com/twitter/.github/blob/main/code-of-conduct.md) in all interactions with the community. +## 🤝 Contributing -## License +We welcome contributions! Please: +1. Follow existing code patterns +2. Include proper documentation headers +3. Test your examples before submitting -Copyright 2021 Twitter, Inc. +## 📄 License -Licensed under the Apache License, Version 2.0: https://www.apache.org/licenses/LICENSE-2.0 +Apache 2.0 - See [LICENSE](LICENSE) diff --git a/Recent-Search/RecentSearchDemo.java b/Recent-Search/RecentSearchDemo.java deleted file mode 100644 index 9072908..0000000 --- a/Recent-Search/RecentSearchDemo.java +++ /dev/null @@ -1,65 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Recent search endpoint - * */ -public class RecentSearchDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace the search term with a term of your choice - String response = search("from:TwitterDev OR from:SnowBotDev OR from:DailyNASA", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the recent search endpoint with a the search term passed to it as a query parameter - * */ - private static String search(String searchString, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/search/recent"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("query", searchString)); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Recent-Search/recent-search.r b/Recent-Search/recent-search.r deleted file mode 100644 index 7c388e5..0000000 --- a/Recent-Search/recent-search.r +++ /dev/null @@ -1,28 +0,0 @@ -require(httr) - - -bearer_token = "" -headers = c( - `Authorization` = sprintf('Bearer %s', bearer_token) -) - - -params = list( - `query` = 'from:TwitterDev', - `max_results` = '10', - `tweet.fields` = 'created_at,lang,conversation_id' -) - - -response <- httr::GET(url = 'https://api.twitter.com/2/tweets/search/recent', httr::add_headers(.headers=headers), query = params) - - -recent_search_body <- - content( - response, - as = 'parsed', - type = 'application/json', - simplifyDataFrame = TRUE - ) - -View(recent_search_body$data) diff --git a/Recent-Search/recent_search.js b/Recent-Search/recent_search.js deleted file mode 100644 index 97a9bf6..0000000 --- a/Recent-Search/recent_search.js +++ /dev/null @@ -1,51 +0,0 @@ -// Search for Tweets within the past seven days -// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = "https://api.twitter.com/2/tweets/search/recent"; - -async function getRequest() { - - // Edit query parameters below - // specify a search query, and any additional fields that are required - // by default, only the Tweet ID and text fields are returned - const params = { - 'query': 'from:twitterdev -is:retweet', - 'tweet.fields': 'author_id' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2RecentSearchJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Recent-Search/recent_search.rb b/Recent-Search/recent_search.rb deleted file mode 100644 index 3f025ef..0000000 --- a/Recent-Search/recent_search.rb +++ /dev/null @@ -1,49 +0,0 @@ -# This script uses your bearer token to authenticate and make a Search request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Recent Search API -search_url = "https://api.twitter.com/2/tweets/search/recent" - -# Set the query value here. Value can be up to 512 characters -query = "from:Twitter OR from:TwitterDev OR from:DailyNasa" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent -query_params = { - "query": query, # Required - "max_results": 10, - # "start_time": "2020-07-01T00:00:00Z", - # "end_time": "2020-07-02T18:00:00Z", - # "expansions": "attachments.poll_ids,attachments.media_keys,author_id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,id,lang", - "user.fields": "description" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -def search_tweets(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2RecentSearchRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = search_tweets(search_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Recent-Tweet-Counts/RecentTweetCountsDemo.java b/Recent-Tweet-Counts/RecentTweetCountsDemo.java deleted file mode 100644 index 09723cf..0000000 --- a/Recent-Tweet-Counts/RecentTweetCountsDemo.java +++ /dev/null @@ -1,66 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Recent Tweet counts endpoint - * */ -public class RecentTweetCountsDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace the search term with a term of your choice - String response = getTweetCounts("from:TwitterDev", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the recent Tweet counts endpoint with a the search term passed to it as a query parameter - * */ - private static String getTweetCounts(String searchString, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/counts/recent"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("query", searchString)); - queryParameters.add(new BasicNameValuePair("granularity", "day")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Recent-Tweet-Counts/recent_tweet_counts.js b/Recent-Tweet-Counts/recent_tweet_counts.js deleted file mode 100644 index 623ea20..0000000 --- a/Recent-Tweet-Counts/recent_tweet_counts.js +++ /dev/null @@ -1,50 +0,0 @@ -// Search for Tweets within the past seven days -// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = "https://api.twitter.com/2/tweets/counts/recent"; - -async function getRequest() { - - // Edit query parameters below and specify a search query - // optional params: start_time,end_time,since_id,until_id,next_token,granularity - const params = { - 'query': 'from:twitterdev', - 'granularity': 'day' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2RecentTweetCountsJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Recent-Tweet-Counts/recent_tweet_counts.py b/Recent-Tweet-Counts/recent_tweet_counts.py deleted file mode 100644 index 6ceafba..0000000 --- a/Recent-Tweet-Counts/recent_tweet_counts.py +++ /dev/null @@ -1,39 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -search_url = "https://api.twitter.com/2/tweets/counts/recent" - -# Optional params: start_time,end_time,since_id,until_id,next_token,granularity -query_params = {'query': 'from:twitterdev','granularity': 'day'} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2RecentTweetCountsPython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("GET", url, auth=bearer_oauth, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - json_response = connect_to_endpoint(search_url, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Recent-Tweet-Counts/recent_tweet_counts.r b/Recent-Tweet-Counts/recent_tweet_counts.r deleted file mode 100644 index 48df1cb..0000000 --- a/Recent-Tweet-Counts/recent_tweet_counts.r +++ /dev/null @@ -1,25 +0,0 @@ -library(httr) - -# Replace the bearer token below with -bearer_token = "" - -headers = c( - `Authorization` = sprintf('Bearer %s', bearer_token) -) - -params = list( - `query` = 'from:twitterdev', - `granularity` = 'day' -) - -response <- httr::GET(url = 'https://api.twitter.com/2/tweets/counts/recent', httr::add_headers(.headers=headers), query = params) - -body <- - content( - response, - as = 'parsed', - type = 'application/json', - simplifyDataFrame = TRUE - ) - -View(body$data) \ No newline at end of file diff --git a/Recent-Tweet-Counts/recent_tweet_counts.rb b/Recent-Tweet-Counts/recent_tweet_counts.rb deleted file mode 100644 index 52bc7bc..0000000 --- a/Recent-Tweet-Counts/recent_tweet_counts.rb +++ /dev/null @@ -1,41 +0,0 @@ -# This script uses your bearer token to authenticate and make a Search request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Recent Search API -search_url = "https://api.twitter.com/2/tweets/counts/recent" - -# Set the query value here. Value can be up to 512 characters -query = "from:TwitterDev" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-counts-recent -query_params = { - "query": query, # Required - "granularity": "day" -} - -def get_tweet_counts(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2RecentTweetCountsRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = get_tweet_counts(search_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Retweets-Lookup/retweeted_by.js b/Retweets-Lookup/retweeted_by.js deleted file mode 100644 index 1a48587..0000000 --- a/Retweets-Lookup/retweeted_by.js +++ /dev/null @@ -1,49 +0,0 @@ -const needle = require("needle"); -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' - -const token = process.env.BEARER_TOKEN; - -// You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for -// You can find an ID by using the Tweet lookup endpoint -const id = "1354143047324299264"; - -const endpointURL = `https://api.twitter.com/2/tweets/${id}/retweeted_by`; - -async function getRequest() { - // These are the parameters for the API request - // by default, only the Tweet ID and text are returned - const params = { - "tweet.fields": "lang,author_id", // Edit optional query parameters here - "user.fields": "created_at", // Edit optional query parameters here - }; - - // this is the HTTP header that adds bearer token authentication - const res = await needle("get", endpointURL, params, { - headers: { - "User-Agent": "v2RetweetedByUsersJS", - authorization: `Bearer ${token}` - }, - }); - - if (res.body) { - return res.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Retweets-Lookup/retweeted_by.py b/Retweets-Lookup/retweeted_by.py deleted file mode 100644 index f171bc4..0000000 --- a/Retweets-Lookup/retweeted_by.py +++ /dev/null @@ -1,56 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' - - -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - user_fields = "user.fields=created_at,description" - # You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for - # You can find an ID by using the Tweet lookup endpoint - id = "1354143047324299264" - # You can adjust ids to include a single Tweets. - # Or you can add to up to 100 comma-separated IDs - url = "https://api.twitter.com/2/tweets/{}/retweeted_by".format(id) - return url, user_fields - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2RetweetedByPython" - return r - - -def connect_to_endpoint(url, user_fields): - response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url, user_fields = create_url() - json_response = connect_to_endpoint(url, user_fields) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Retweets-Lookup/retweeted_by.rb b/Retweets-Lookup/retweeted_by.rb deleted file mode 100644 index 5f80461..0000000 --- a/Retweets-Lookup/retweeted_by.rb +++ /dev/null @@ -1,43 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - - -# You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for -# You can find an ID by using the Tweet lookup endpoint -id = "1412865600439738368" - -url = "https://api.twitter.com/2/tweets/#{id}/retweeted_by" - -params = { - # User fields are adjustable, options include: - # created_at, description, entities, id, location, name, - # pinned_tweet_id, profile_image_url, protected, - # public_metrics, url, username, verified, and withheld - "user.fields": "created_at,description", -} - -def retweeted_by_users(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2RetweetedbyUsersRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = retweeted_by_users(url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.js b/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.js deleted file mode 100644 index a9c7702..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.js +++ /dev/null @@ -1,142 +0,0 @@ -// Retrieve accounts muted by authenticated user -// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start -const got = require("got"); -const crypto = require("crypto"); -const OAuth = require("oauth-1.0a"); -const qs = require("querystring"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; -const endpointURL = `https://api.twitter.com/2/users/${id}/timelines/reverse_chronological`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = - "https://api.twitter.com/oauth/request_token?oauth_callback=oob"; -const authorizeURL = new URL("https://api.twitter.com/oauth/authorize"); -const accessTokenURL = "https://api.twitter.com/oauth/access_token"; -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret, - }, - signature_method: "HMAC-SHA1", - hash_function: (baseString, key) => - crypto.createHmac("sha1", key).update(baseString).digest("base64"), -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: requestTokenURL, - method: "POST", - }) - ); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function accessToken({ oauth_token, oauth_token_secret }, verifier) { - const authHeader = oauth.toHeader( - oauth.authorize({ - url: accessTokenURL, - method: "POST", - }) - ); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"], - }, - }); - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error("Cannot get an OAuth request token"); - } -} - -async function getRequest({ oauth_token, oauth_token_secret }) { - const token = { - key: oauth_token, - secret: oauth_token_secret, - }; - - const authHeader = oauth.toHeader( - oauth.authorize( - { - url: endpointURL, - method: "GET", - }, - token - ) - ); - - const req = await got.get(endpointURL, { - responseType: "json", - headers: { - Authorization: authHeader["Authorization"], - "user-agent": "v2ReverseChronHomeTimelinesJS", - }, - }); - if (req.body) { - return req.body; - } else { - throw new Error("Unsuccessful request"); - } -} - -(async () => { - try { - // Get request token - const oAuthRequestToken = await requestToken(); - // Get authorization - authorizeURL.searchParams.append( - "oauth_token", - oAuthRequestToken.oauth_token - ); - console.log("Please go here and authorize:", authorizeURL.href); - const pin = await input("Paste the PIN here: "); - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null, - }); - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.py b/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.py deleted file mode 100644 index 6d6c5a6..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.py +++ /dev/null @@ -1,71 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -params = {"tweet.fields": "created_at"} # Tweet ID and text are included by default. - -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -response = oauth.get( - "https://api.twitter.com/2/users/{}/timelines/reverse_chronological".format(id),params=params -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.rb b/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.rb deleted file mode 100644 index 36cdf3b..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth1a-user/reverse-chron-home-timeline.rb +++ /dev/null @@ -1,80 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a Mutes lookup request (by usernames) with OAuth 1.0a authentication (user context) -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -url = "https://api.twitter.com/2/users/#{id}/timelines/reverse_chronological" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - - -def reverse_chron_home_timeline(url, oauth_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2ReverseChronHomeTimelineRuby" - } - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - - - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = reverse_chron_home_timeline(url, oauth_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-java-sdk.java b/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-java-sdk.java deleted file mode 100644 index 4605598..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-java-sdk.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.twitter.clientlib.auth; - -import java.util.HashSet; -import java.util.Scanner; -import java.util.Set; - -import com.github.scribejava.core.model.OAuth2AccessToken; -import com.github.scribejava.core.pkce.PKCE; -import com.github.scribejava.core.pkce.PKCECodeChallengeMethod; -import com.twitter.clientlib.TwitterCredentialsBearer; -import com.twitter.clientlib.ApiClient; -import com.twitter.clientlib.ApiException; -import com.twitter.clientlib.Configuration; -import com.twitter.clientlib.auth.*; -import com.twitter.clientlib.model.*; -import com.twitter.clientlib.TwitterCredentialsOAuth2; - - -import com.twitter.clientlib.api.TwitterApi; - -import com.twitter.clientlib.api.BookmarksApi; -import java.util.List; -import java.util.Set; -import java.util.Arrays; -import java.util.HashSet; -import java.time.OffsetDateTime; -import org.json.*; - -/** -* This is an example of getting an OAuth2 access token and using it to call an API. -* It's expected to set TWITTER_OAUTH2_CLIENT_ID & TWITTER_OAUTH2_CLIENT_SECRET in TwitterCredentialsOAuth2 -* -* Example steps: -* 1. Getting the App Authorization URL. -* 2. User should click the URL and authorize it. -* 3. After receiving the access token, setting the values into TwitterCredentialsOAuth2. -* 4. Call the API. -*/ - -public class OAuth20GetAccessToken { - - public static void main(String[] args) { - OAuth20GetAccessToken example = new OAuth20GetAccessToken(); - TwitterCredentialsOAuth2 credentials = new TwitterCredentialsOAuth2("REPLACE-WITH-CLIENT-ID", - "REPLACE-WITH-CLIENT-SECRET", - null, - null); - - OAuth2AccessToken accessToken = example.getAccessToken(credentials); - if (accessToken == null) { - return; - } - - // Setting the access & refresh tokens into TwitterCredentialsOAuth2 - credentials.setTwitterOauth2AccessToken(accessToken.getAccessToken()); - credentials.setTwitterOauth2RefreshToken(accessToken.getRefreshToken()); - example.callApi(credentials); - } - - public OAuth2AccessToken getAccessToken(TwitterCredentialsOAuth2 credentials) { - TwitterOAuth20Service service = new TwitterOAuth20Service( - credentials.getTwitterOauth2ClientId(), - credentials.getTwitterOAuth2ClientSecret(), - "https://www.example.com/oauth", - "offline.access tweet.read users.read"); - - OAuth2AccessToken accessToken = null; - try { - final Scanner in = new Scanner(System.in, "UTF-8"); - System.out.println("Fetching the Authorization URL..."); - - final String secretState = "state"; - PKCE pkce = new PKCE(); - pkce.setCodeChallenge("challenge"); - pkce.setCodeChallengeMethod(PKCECodeChallengeMethod.PLAIN); - pkce.setCodeVerifier("challenge"); - String authorizationUrl = service.getAuthorizationUrl(pkce, secretState); - - System.out.println("Go to the Authorization URL and authorize your App:\n" + - authorizationUrl + "\nAfter that paste the authorization code here\n>>"); - final String code = in.nextLine(); - System.out.println("\nTrading the Authorization Code for an Access Token..."); - accessToken = service.getAccessToken(pkce, code); - - System.out.println("Access token: " + accessToken.getAccessToken()); - System.out.println("Refresh token: " + accessToken.getRefreshToken()); - } catch (Exception e) { - System.err.println("Error while getting the access token:\n " + e); - e.printStackTrace(); - } - return accessToken; - } - - public void callApi(TwitterCredentialsOAuth2 credentials) { - TwitterApi apiInstance = new TwitterApi(); - apiInstance.setTwitterCredentials(credentials); - - // Set the params values - String sinceId = "791775337160081409"; // String | The minimum Tweet ID to be included in the result set. This parameter takes precedence over start_time if both are specified. - String untilId = "1346889436626259968"; // String | The maximum Tweet ID to be included in the result set. This parameter takes precedence over end_time if both are specified. - Integer maxResults = 56; // Integer | The maximum number of results - String paginationToken = "paginationToken_example"; // String | This parameter is used to get the next 'page' of results. - OffsetDateTime startTime = OffsetDateTime.parse("2021-02-01T18:40:40.000Z"); // OffsetDateTime | YYYY-MM-DDTHH:mm:ssZ. The earliest UTC timestamp from which the Tweets will be provided. The since_id parameter takes precedence if it is also specified. - OffsetDateTime endTime = OffsetDateTime.parse("2021-02-14T18:40:40.000Z"); // OffsetDateTime | YYYY-MM-DDTHH:mm:ssZ. The latest UTC timestamp to which the Tweets will be provided. The until_id parameter takes precedence if it is also specified. - Set expansions = new HashSet<>(Arrays.asList()); // Set | A comma separated list of fields to expand. - Set tweetFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Tweet fields to display. - Set userFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of User fields to display. - Set mediaFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Media fields to display. - Set placeFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Place fields to display. - Set pollFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Poll fields to display. - - try { - //Gets the authorized user ID and parses it into an JSON object - SingleUserLookupResponse userData = apiInstance.users().findMyUser(null, null, null); - String jsonString = userData.getData().toJson(); - JSONObject obj = new JSONObject(jsonString); - String userId = obj.getString("id"); - - //Passes the parsed ID into the userIdTimeline request - GenericTweetsTimelineResponse result = apiInstance.tweets().usersIdTimeline(userId, sinceId, untilId, maxResults, null, paginationToken, startTime, endTime, expansions, tweetFields, userFields, mediaFields, placeFields, pollFields); - System.out.println(result); - } catch (ApiException e) { - System.err.println("Exception when calling UsersApi#usersIdTimeline"); - System.err.println("Status code: " + e.getCode()); - System.err.println("Reason: " + e.getResponseBody()); - System.err.println("Response headers: " + e.getResponseHeaders()); - e.printStackTrace(); - } - } -} diff --git a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-js-sdk.js b/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-js-sdk.js deleted file mode 100644 index b0b4cab..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline-js-sdk.js +++ /dev/null @@ -1,92 +0,0 @@ -const { Client, auth } = require("twitter-api-sdk"); - -const readline = require("readline").createInterface({ - input: process.stdin, - output: process.stdout, -}); - -//Helper function to parse callback -const getQueryStringParams = (query) => { - return query - ? (/^[?#]/.test(query) ? query.slice(1) : query) - .split(/[\?\&]/) - .reduce((params, param) => { - let [key, value] = param.split("="); - params[key] = value - ? decodeURIComponent(value.replace(/\+/g, " ")) - : ""; - return params; - }, {}) - : {}; -}; - -//Helper terminal input function -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CLIENT_ID='YOUR-CLIENT-ID' -// export CLIENET_SECRET='YOUR-CLIENT-SECRET' -const CLIENT_ID = process.env.CLIENT_ID; -const CLIENT_SECRET = process.env.CLIENT_SECRET; - -// Optional parameters for additional payload data -const params = { - expansions: "author_id", - "user.fields": ["username", "created_at"], - "tweet.fields": ["geo", "entities", "context_annotations"], -}; - -(async () => { - const authClient = new auth.OAuth2User({ - client_id: CLIENT_ID, - client_secret: CLIENT_SECRET, - callback: "https://www.example.com/oauth", - scopes: ["tweet.read", "users.read"], - }); - - const client = new Client(authClient); - const STATE = "my-state"; - - //Get authorization - const authUrl = authClient.generateAuthURL({ - state: STATE, - code_challenge: "challenge", - }); - - console.log(`Please go here and authorize:`, authUrl); - - //Input users callback url in termnial - const redirectCallback = await input("Paste the redirected callback here: "); - - try { - //Parse callback - const { state, code } = getQueryStringParams(redirectCallback); - if (state !== STATE) { - console.log("State isn't matching"); - } - //Gets access token - await authClient.requestAccessToken(code); - - //Get the user ID - const { - data: { id }, - } = await client.users.findMyUser(); - - //Makes api call - const getUsersTimeline = await client.tweets.usersIdTimeline(id, params); - console.dir(getUsersTimeline, { - depth: null, - }); - process.exit(); - } catch (error) { - console.log(error); - } -})(); diff --git a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.py b/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.py deleted file mode 100644 index ed6e2f8..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.py +++ /dev/null @@ -1,112 +0,0 @@ -import base64 -import hashlib -import os -import re -import json -import requests -from requests.auth import AuthBase, HTTPBasicAuth -from requests_oauthlib import OAuth2Session - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = os.environ.get("CLIENT_ID") - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = os.environ.get("CLIENT_SECRET") - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Set the scopes -scopes = ["tweet.read", "users.read", "offline.access"] - -# Create a code verifier -code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") -code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) - -# Create a code challenge -code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() -code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") -code_challenge = code_challenge.replace("=", "") - -# Start an OAuth 2.0 session -oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) - -# Create an authorize URL -auth_url = "https://twitter.com/i/oauth2/authorize" -authorization_url, state = oauth.authorization_url( - auth_url, code_challenge=code_challenge, code_challenge_method="S256" -) - -# Visit the URL to authorize your App to make requests on behalf of a user -print( - "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" -) -print(authorization_url) - -# Paste in your authorize URL to complete the request -authorization_response = input( - "Paste in the full URL after you've authorized your App:\n" -) - -# Fetch your access token -token_url = "https://api.twitter.com/2/oauth2/token" - -# The following line of code will only work if you are using a type of App that is a public client -auth = False - -# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. - -# Please remove the comment on the following line if you are using a type of App that is a confidential client -# auth = HTTPBasicAuth(client_id, client_secret) - -token = oauth.fetch_token( - token_url=token_url, - authorization_response=authorization_response, - auth=auth, - client_id=client_id, - include_client_id=True, - code_verifier=code_verifier, -) - -# Your access token -access = token["access_token"] - -# Make a request to the users/me endpoint to get your user ID -user_me = requests.request( - "GET", - "https://api.twitter.com/2/users/me", - headers={"Authorization": "Bearer {}".format(access)}, -).json() - -# -# -# Now that we have user authorization, let's look up their home timeline. -# -# - -# Set the user. This defaults to the ID of the authorizing user. -user_id = user_me["data"]["id"] - -# Set the url. -url = "https://api.twitter.com/2/users/{}/timelines/reverse_chronological".format(user_id) - -headers = { - "Authorization": "Bearer {}".format(access), - "User-Agent": "ReverseChronSampleCode", -} -response = requests.request("GET", url, headers=headers) -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.rb b/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.rb deleted file mode 100644 index aeedb1a..0000000 --- a/Reverse-Chron-Home-Timeline/OAuth2-user/reverse-chron-home-timeline.rb +++ /dev/null @@ -1,110 +0,0 @@ -require 'json' -require 'typhoeus' -require 'twitter_oauth2' - -# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_ID='your-client-id' -client_id = ENV["CLIENT_ID"] - -# If you have selected a type of App that is a confidential client you will need to set a client secret. -# Confidential Clients securely authenticate with the authorization server. - -# Inside your terminal you will need to set an enviornment variable -# export CLIENT_SECRET='your-client-secret' - -# Remove the comment on the following line if you are using a confidential client -# client_secret = ENV["CLIENT_SECRET"] - - -# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. -redirect_uri = "https://www.example.com" - -# Start an OAuth 2.0 session with a public client -client = TwitterOAuth2::Client.new( - identifier: "#{client_id}", - redirect_uri: "#{redirect_uri}" -) - -# Start an OAuth 2.0 session with a confidential client - -# Remove the comment on the following lines if you are using a confidential client -# client = TwitterOAuth2::Client.new( -# identifier: "#{client_id}", -# secret: "#{client_secret}", -# redirect_uri: "#{redirect_uri}" -# ) - -# Create your authorize url -authorization_url = client.authorization_uri( - # Update scopes if needed - scope: [ - :'users.read', - :'tweet.read', - :'offline.access' - ] -) - -# Set code verifier and state -code_verifier = client.code_verifier -state = client.state - -# Visit the URL to authorize your App to make requests on behalf of a user -print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' -puts authorization_url -`open "#{authorization_url}"` - -print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush - -# Fetch your access token -full_text = gets.chop -new_code = full_text.split("code=") -code = new_code[1] -client.authorization_code = code - -# Your access token -token_response = client.access_token! code_verifier - -# Make a request to the users/me endpoint to get your user ID -def users_me(url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "ReverseChronHomeTimelineSampleCode", - "Authorization": "Bearer #{token_response}" - }, - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -url = "https://api.twitter.com/2/users/me" -me_response = users_me(url, token_response) - -json_s = JSON.parse(me_response.body) -user_id = json_s["data"]["id"] - -# Make a request to the reverse chronological home timeline endpoint -url = "https://api.twitter.com/2/users/#{user_id}/timelines/reverse_chronological" - - -def reverse_chron_timeline(url, token_response) - options = { - method: 'get', - headers: { - "User-Agent": "ReverseChronTimelinesSampleCode", - "Authorization": "Bearer #{token_response}" - } - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = reverse_chron_timeline(url, token_response) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Sampled-Stream/SampledStream.java b/Sampled-Stream/SampledStream.java deleted file mode 100644 index 001cb95..0000000 --- a/Sampled-Stream/SampledStream.java +++ /dev/null @@ -1,60 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URISyntaxException; - -/* - * Sample code to demonstrate the use of the Sampled Stream endpoint - * */ -public class SampledStreamDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - connectStream(bearerToken); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - - } - - /* - * This method calls the sample stream endpoint and streams Tweets from it - * */ - private static void connectStream(String bearerToken) throws IOException, URISyntaxException { - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets/sample/stream"); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - BufferedReader reader = new BufferedReader(new InputStreamReader((entity.getContent()))); - String line = reader.readLine(); - while (line != null) { - System.out.println(line); - line = reader.readLine(); - } - } - - } -} diff --git a/Sampled-Stream/sampled_stream.js b/Sampled-Stream/sampled_stream.js deleted file mode 100644 index 4a0d5d8..0000000 --- a/Sampled-Stream/sampled_stream.js +++ /dev/null @@ -1,60 +0,0 @@ -// Open a live stream of roughly 1% random sample of publicly available Tweets -// https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/quick-start - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const streamURL = 'https://api.twitter.com/2/tweets/sample/stream'; - -function streamConnect(retryAttempt) { - - const stream = needle.get(streamURL, { - headers: { - "User-Agent": "v2SampleStreamJS", - "Authorization": `Bearer ${token}` - }, - timeout: 20000 - }); - - stream.on('data', data => { - try { - const json = JSON.parse(data); - console.log(json); - // A successful connection resets retry count. - retryAttempt = 0; - } catch (e) { - // Catches error in case of 401 unauthorized error status. - if (data.status === 401) { - console.log(data); - process.exit(1); - } else if (data.detail === "This stream is currently at the maximum allowed connection limit.") { - console.log(data.detail) - process.exit(1) - } else { - // Keep alive signal received. Do nothing. - } - } - }).on('err', error => { - if (error.code !== 'ECONNRESET') { - console.log(error.code); - process.exit(1); - } else { - // This reconnection logic will attempt to reconnect when a disconnection is detected. - // To avoid rate limits, this logic implements exponential backoff, so the wait time - // will increase if the client cannot reconnect to the stream. - setTimeout(() => { - console.warn("A connection error occurred. Reconnecting...") - streamConnect(++retryAttempt); - }, 2 ** retryAttempt); - } - }); - return stream; -} - -(async () => { - streamConnect(0) -})(); diff --git a/Sampled-Stream/sampled_stream.rb b/Sampled-Stream/sampled_stream.rb deleted file mode 100644 index f1c356d..0000000 --- a/Sampled-Stream/sampled_stream.rb +++ /dev/null @@ -1,51 +0,0 @@ -# This script connects to the Sample stream endpoint and outputs data - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -stream_url = "https://api.twitter.com/2/tweets/sample/stream" - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream -params = { - # "expansions": "author_id,referenced_tweets.id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "name" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -def stream_connect(url, bearer_token, params) - options = { - timeout: 20, - method: 'get', - headers: { - "User-Agent": "v2SampledStreamRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - request.on_body do |chunk| - puts chunk - end - request.run -end - -# Listen to the stream. -# This reconnection logic will attempt to reconnect when a disconnection is detected. -# To avoid rate limites, this logic implements exponential backoff, so the wait time -# will increase if the client cannot reconnect to the stream. -timeout = 0 -while true - stream_connect(stream_url, bearer_token, params) - sleep 2 ** timeout - timeout += 1 -end diff --git a/Search-Spaces/SearchSpacesDemo.java b/Search-Spaces/SearchSpacesDemo.java deleted file mode 100644 index bcde135..0000000 --- a/Search-Spaces/SearchSpacesDemo.java +++ /dev/null @@ -1,66 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Spaces lookup endpoint - * */ -public class SpacesLookupDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace SPACE_ID with the ID of a Space - String response = getSpaceById("SPACE_ID", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the Spaces lookup endpoint with the ID passed to it as a query parameter - * */ - private static String getSpaceById(String spaceId, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/spaces"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("ids", spaceId)); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("User-Agent", "v2SpacesLookupJava"); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Search-Spaces/search_spaces.js b/Search-Spaces/search_spaces.js deleted file mode 100644 index f7876a9..0000000 --- a/Search-Spaces/search_spaces.js +++ /dev/null @@ -1,51 +0,0 @@ -// Lookup Spaces by ID -// https://developer.twitter.com/en/docs/twitter-api/spaces/lookup - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = `https://api.twitter.com/2/spaces/search`; - -async function getRequest() { - - // Edit query parameters below and specify a search query - // optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at - const params = { - 'query': 'NBA', // Replace the value with your search term - 'space.fields': 'title,created_at', - 'expansions': 'creator_id' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2SpacesSearchJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Search-Spaces/search_spaces.py b/Search-Spaces/search_spaces.py deleted file mode 100644 index 430825e..0000000 --- a/Search-Spaces/search_spaces.py +++ /dev/null @@ -1,40 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -search_url = "https://api.twitter.com/2/spaces/search" - -search_term = 'NBA' # Replace this value with your search term - -# Optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at -query_params = {'query': search_term, 'space.fields': 'title,created_at', 'expansions': 'creator_id'} - - -def create_headers(bearer_token): - headers = { - "Authorization": "Bearer {}".format(bearer_token), - "User-Agent": "v2SpacesSearchPython" - } - return headers - - -def connect_to_endpoint(url, headers, params): - response = requests.request("GET", search_url, headers=headers, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - headers = create_headers(bearer_token) - json_response = connect_to_endpoint(search_url, headers, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/Search-Spaces/search_spaces.rb b/Search-Spaces/search_spaces.rb deleted file mode 100644 index 228c8dd..0000000 --- a/Search-Spaces/search_spaces.rb +++ /dev/null @@ -1,42 +0,0 @@ -# This script uses your bearer token to authenticate and make a Spaces lookup request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on macOS, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL -spaces_search_url = "https://api.twitter.com/2/spaces/search" - -# Replace this value with your search term -query = "NBA" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference -query_params = { - "query": query, # Required - "space.fields": 'title,created_at', - 'expansions': 'creator_id' -} - -def get_space(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2SpacesSearchRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = get_space(spaces_search_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Spaces-Lookup/SpacesLookupDemo.java b/Spaces-Lookup/SpacesLookupDemo.java deleted file mode 100644 index bcde135..0000000 --- a/Spaces-Lookup/SpacesLookupDemo.java +++ /dev/null @@ -1,66 +0,0 @@ -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -/* - * Sample code to demonstrate the use of the Spaces lookup endpoint - * */ -public class SpacesLookupDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace SPACE_ID with the ID of a Space - String response = getSpaceById("SPACE_ID", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the Spaces lookup endpoint with the ID passed to it as a query parameter - * */ - private static String getSpaceById(String spaceId, String bearerToken) throws IOException, URISyntaxException { - String searchResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/spaces"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("ids", spaceId)); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("User-Agent", "v2SpacesLookupJava"); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - searchResponse = EntityUtils.toString(entity, "UTF-8"); - } - return searchResponse; - } - -} \ No newline at end of file diff --git a/Spaces-Lookup/spaces_lookup.js b/Spaces-Lookup/spaces_lookup.js deleted file mode 100644 index 623ea20..0000000 --- a/Spaces-Lookup/spaces_lookup.js +++ /dev/null @@ -1,50 +0,0 @@ -// Search for Tweets within the past seven days -// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointUrl = "https://api.twitter.com/2/tweets/counts/recent"; - -async function getRequest() { - - // Edit query parameters below and specify a search query - // optional params: start_time,end_time,since_id,until_id,next_token,granularity - const params = { - 'query': 'from:twitterdev', - 'granularity': 'day' - } - - const res = await needle('get', endpointUrl, params, { - headers: { - "User-Agent": "v2RecentTweetCountsJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Spaces-Lookup/spaces_lookup.py b/Spaces-Lookup/spaces_lookup.py deleted file mode 100644 index 20b586e..0000000 --- a/Spaces-Lookup/spaces_lookup.py +++ /dev/null @@ -1,38 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -search_url = "https://api.twitter.com/2/spaces" - -# Optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at -query_params = {'ids': 'SPACE_ID', 'space.fields': 'title,created_at', 'expansions': 'creator_id'} - - -def create_headers(bearer_token): - headers = { - "Authorization": "Bearer {}".format(bearer_token), - "User-Agent": "v2SpacesLookupPython" - } - return headers - - -def connect_to_endpoint(url, headers, params): - response = requests.request("GET", search_url, headers=headers, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception(response.status_code, response.text) - return response.json() - - -def main(): - headers = create_headers(bearer_token) - json_response = connect_to_endpoint(search_url, headers, query_params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/Spaces-Lookup/spaces_lookup.rb b/Spaces-Lookup/spaces_lookup.rb deleted file mode 100644 index b64340c..0000000 --- a/Spaces-Lookup/spaces_lookup.rb +++ /dev/null @@ -1,42 +0,0 @@ -# This script uses your bearer token to authenticate and make a Spaces lookup request - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on macOS, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for Spaces lookup -spaces_lookup_url = "https://api.twitter.com/2/spaces" - -# Replace SPACE_ID with the ID of a Space -id = "SPACE_ID" - -# Add or remove parameters below to adjust the query and response fields within the payload -# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference -query_params = { - "ids": id, # Required - "space.fields": 'title,created_at', - 'expansions': 'creator_id' -} - -def get_space(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent": "v2SpacesLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = get_space(spaces_lookup, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Tweet-Lookup/TweetsDemo.java b/Tweet-Lookup/TweetsDemo.java deleted file mode 100644 index c197ca4..0000000 --- a/Tweet-Lookup/TweetsDemo.java +++ /dev/null @@ -1,65 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 Tweets endpoint - * */ -public class TweetsDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace comma separated ids with Tweets Ids of your choice - String response = getTweets("1138505981460193280,1261326399320715264", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 Tweets endpoint with ids as query parameter - * */ - private static String getTweets(String ids, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/tweets"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("ids", ids)); - queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} \ No newline at end of file diff --git a/Tweet-Lookup/get_tweets_with_bearer_token.js b/Tweet-Lookup/get_tweets_with_bearer_token.js deleted file mode 100644 index 6a1635c..0000000 --- a/Tweet-Lookup/get_tweets_with_bearer_token.js +++ /dev/null @@ -1,53 +0,0 @@ -// Get Tweet objects by ID, using bearer token authentication -// https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/quick-start - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointURL = "https://api.twitter.com/2/tweets?ids="; - -async function getRequest() { - - // These are the parameters for the API request - // specify Tweet IDs to fetch, and any additional fields that are required - // by default, only the Tweet ID and text are returned - const params = { - "ids": "1278747501642657792,1255542774432063488", // Edit Tweet IDs to look up - "tweet.fields": "lang,author_id", // Edit optional query parameters here - "user.fields": "created_at" // Edit optional query parameters here - } - - // this is the HTTP header that adds bearer token authentication - const res = await needle('get', endpointURL, params, { - headers: { - "User-Agent": "v2TweetLookupJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Tweet-Lookup/get_tweets_with_bearer_token.py b/Tweet-Lookup/get_tweets_with_bearer_token.py deleted file mode 100644 index 5f1cafa..0000000 --- a/Tweet-Lookup/get_tweets_with_bearer_token.py +++ /dev/null @@ -1,55 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - tweet_fields = "tweet.fields=lang,author_id" - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - ids = "ids=1278747501642657792,1255542774432063488" - # You can adjust ids to include a single Tweets. - # Or you can add to up to 100 comma-separated IDs - url = "https://api.twitter.com/2/tweets?{}&{}".format(ids, tweet_fields) - return url - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2TweetLookupPython" - return r - - -def connect_to_endpoint(url): - response = requests.request("GET", url, auth=bearer_oauth) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url = create_url() - json_response = connect_to_endpoint(url) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Tweet-Lookup/get_tweets_with_bearer_token.r b/Tweet-Lookup/get_tweets_with_bearer_token.r deleted file mode 100644 index 62221cb..0000000 --- a/Tweet-Lookup/get_tweets_with_bearer_token.r +++ /dev/null @@ -1,21 +0,0 @@ -require(httr) - -bearer_token <- "" - -headers <- c(`Authorization` = sprintf('Bearer %s', bearer_token)) - -params <- list(`tweet.fields` = 'created_at') - -ids <- '1293593516040269825' - -url_ids <- - sprintf('https://api.twitter.com/2/tweets?ids=%s', ids) - -response <- - httr::GET(url = url_ids, - httr::add_headers(.headers = headers), - query = params) - - -obj <- httr::content(response, as = "text") -print(obj) diff --git a/Tweet-Lookup/get_tweets_with_bearer_token.rb b/Tweet-Lookup/get_tweets_with_bearer_token.rb deleted file mode 100644 index c4e5973..0000000 --- a/Tweet-Lookup/get_tweets_with_bearer_token.rb +++ /dev/null @@ -1,45 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified Tweet objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -tweet_lookup_url = "https://api.twitter.com/2/tweets" - -# Specify the Tweet IDs that you want to lookup below (to 100 per request) -tweet_ids = "1261326399320715264,1278347468690915330" - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference -params = { - "ids": tweet_ids, - # "expansions": "author_id,referenced_tweets.id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "name" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -def tweet_lookup(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2TweetLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = tweet_lookup(tweet_lookup_url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Tweet-Lookup/get_tweets_with_user_context.js b/Tweet-Lookup/get_tweets_with_user_context.js deleted file mode 100644 index 06b875c..0000000 --- a/Tweet-Lookup/get_tweets_with_user_context.js +++ /dev/null @@ -1,150 +0,0 @@ -// Get Tweet objects by ID, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/quick-start - -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// These are the parameters for the API request -// specify Tweet IDs to fetch, and any additional fields that are required -// by default, only the Tweet ID and text are returned -const tweetIDs = '1278747501642657792,1275828087666679809'; // Edit the Tweet IDs to look up -const params = 'tweet.fields=lang,author_id&user.fields=created_at'; // Edit optional query parameters here - -const endpointURL = `https://api.twitter.com/2/tweets?ids=${tweetIDs}&${params}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; - -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'GET' - }, token)); - - const req = await got(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2TweetLookupJS" - } - }); - - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - try { - - // Get request token - const oAuthRequestToken = await requestToken(); - - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Tweet-Lookup/get_tweets_with_user_context.py b/Tweet-Lookup/get_tweets_with_user_context.py deleted file mode 100644 index e66becb..0000000 --- a/Tweet-Lookup/get_tweets_with_user_context.py +++ /dev/null @@ -1,77 +0,0 @@ -from requests_oauthlib import OAuth1Session -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - -consumer_key = os.environ.get("CONSUMER_KEY") -consumer_secret = os.environ.get("CONSUMER_SECRET") - -# You can adjust ids to include a single Tweets -# Or you can add to up to 100 comma-separated IDs -params = {"ids": "1278747501642657792", "tweet.fields": "created_at"} -# Tweet fields are adjustable. -# Options include: -# attachments, author_id, context_annotations, -# conversation_id, created_at, entities, geo, id, -# in_reply_to_user_id, lang, non_public_metrics, organic_metrics, -# possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, -# source, text, and withheld - -request_token_url = "https://api.twitter.com/oauth/request_token" -oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) - -try: - fetch_response = oauth.fetch_request_token(request_token_url) -except ValueError: - print( - "There may have been an issue with the consumer_key or consumer_secret you entered." - ) - -resource_owner_key = fetch_response.get("oauth_token") -resource_owner_secret = fetch_response.get("oauth_token_secret") -print("Got OAuth token: %s" % resource_owner_key) - -# Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" -authorization_url = oauth.authorization_url(base_authorization_url) -print("Please go here and authorize: %s" % authorization_url) -verifier = input("Paste the PIN here: ") - -# Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=resource_owner_key, - resource_owner_secret=resource_owner_secret, - verifier=verifier, -) -oauth_tokens = oauth.fetch_access_token(access_token_url) - - -access_token = oauth_tokens["oauth_token"] -access_token_secret = oauth_tokens["oauth_token_secret"] - -# Make the request -oauth = OAuth1Session( - consumer_key, - client_secret=consumer_secret, - resource_owner_key=access_token, - resource_owner_secret=access_token_secret, -) - -response = oauth.get( - "https://api.twitter.com/2/tweets", params=params -) - -if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format(response.status_code, response.text) - ) - -print("Response code: {}".format(response.status_code)) -json_response = response.json() -print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Tweet-Lookup/get_tweets_with_user_context.rb b/Tweet-Lookup/get_tweets_with_user_context.rb deleted file mode 100644 index e900296..0000000 --- a/Tweet-Lookup/get_tweets_with_user_context.rb +++ /dev/null @@ -1,91 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a Tweet lookup request (by IDs) with OAuth 1.0a authentication (user context) - -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Returns a Tweet object for one or more Tweets IDs as specified by the request -tweet_lookup_url = "https://api.twitter.com/2/tweets" - -# Specify the Tweet IDs that you want to lookup below (to 100 per request) -tweet_ids = "1261326399320715264,1278347468690915330" - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference -query_params = { - "ids": tweet_ids, - # "expansions": "author_id,referenced_tweets.id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "name" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - -def tweet_lookup(url, oauth_params, query_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2TweetLookupRuby" - }, - params: query_params - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = tweet_lookup(tweet_lookup_url, oauth_params, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/Usage Tweets/UsageTweetsDemo.java b/Usage Tweets/UsageTweetsDemo.java deleted file mode 100644 index 38f588f..0000000 --- a/Usage Tweets/UsageTweetsDemo.java +++ /dev/null @@ -1,58 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 Usage Tweets endpoint - * */ -public class UsageTweetsDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - String response = getUsageTweets(bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 Usage Tweets endpoint - * */ - private static String getUsageTweets(String bearerToken) throws IOException, URISyntaxException { - String usageTweetsResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/usage/tweets"); - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - usageTweetsResponse = EntityUtils.toString(entity, "UTF-8"); - } - return usageTweetsResponse; - } -} \ No newline at end of file diff --git a/Usage Tweets/get_usage_tweets.js b/Usage Tweets/get_usage_tweets.js deleted file mode 100644 index 53df3be..0000000 --- a/Usage Tweets/get_usage_tweets.js +++ /dev/null @@ -1,44 +0,0 @@ -// Get Tweets Usage -// https://developer.twitter.com/en/docs/twitter-api/usage/tweets - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointURL = "https://api.twitter.com/2/usage/tweets"; - -async function getRequest() { - - // this is the HTTP header that adds bearer token authentication - const res = await needle('get', endpointURL, { - headers: { - "User-Agent": "v2UsageTweetsJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/Usage Tweets/get_usage_tweets.py b/Usage Tweets/get_usage_tweets.py deleted file mode 100644 index e2842aa..0000000 --- a/Usage Tweets/get_usage_tweets.py +++ /dev/null @@ -1,38 +0,0 @@ -import requests -import os -import json - -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2UsageTweetsPython" - return r - - -def connect_to_endpoint(url): - response = requests.request("GET", url, auth=bearer_oauth) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url = "https://api.twitter.com/2/usage/tweets" - json_response = connect_to_endpoint(url) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/Usage Tweets/get_usage_tweets.rb b/Usage Tweets/get_usage_tweets.rb deleted file mode 100644 index 6bd93bb..0000000 --- a/Usage Tweets/get_usage_tweets.rb +++ /dev/null @@ -1,29 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the Usage - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -usage_tweets_url = "https://api.twitter.com/2/usage/tweets" - -def usage_tweets(url, bearer_token) - options = { - method: 'get', - headers: { - "User-Agent": "v2UsageTweetsRuby", - "Authorization": "Bearer #{bearer_token}" - } - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = usage_tweets(usage_tweets_url, bearer_token) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Lookup/UsersDemo.java b/User-Lookup/UsersDemo.java deleted file mode 100644 index 51826a1..0000000 --- a/User-Lookup/UsersDemo.java +++ /dev/null @@ -1,66 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 Users endpoint - * */ -public class UsersDemo { - - // To set your enviornment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace comma separated usernames with usernames of your choice - String response = getUsers("TwitterDev,TwitterEng", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 Users endpoint with usernames as query parameter - * */ - private static String getUsers(String usernames, String bearerToken) throws IOException, URISyntaxException { - String userResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder("https://api.twitter.com/2/users/by"); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("usernames", usernames)); - queryParameters.add(new BasicNameValuePair("user.fields", "created_at,description,pinned_tweet_id")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - userResponse = EntityUtils.toString(entity, "UTF-8"); - } - return userResponse; - } - -} \ No newline at end of file diff --git a/User-Lookup/get_users_me_with_user_context.js b/User-Lookup/get_users_me_with_user_context.js deleted file mode 100644 index 10e4bb9..0000000 --- a/User-Lookup/get_users_me_with_user_context.js +++ /dev/null @@ -1,146 +0,0 @@ -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// These are the parameters for the API request -// specify Tweet IDs to fetch, and any additional fields that are required -// by default, only the Tweet ID and text are returned -const params = 'user.fields=created_at,description&expansions=pinned_tweet_id' // Edit optional query parameters here - -const endpointURL = `https://api.twitter.com/2/users/me?{params}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; - -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'GET' - }, token)); - - const req = await got(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UserLookupJS" - } - }); - - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - try { - - // Get request token - const oAuthRequestToken = await requestToken(); - - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/User-Lookup/get_users_me_with_user_context.rb b/User-Lookup/get_users_me_with_user_context.rb deleted file mode 100644 index 103bec5..0000000 --- a/User-Lookup/get_users_me_with_user_context.rb +++ /dev/null @@ -1,80 +0,0 @@ -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -user_lookup_url = "https://api.twitter.com/2/users/me" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users -query_params = { - # "expansions": "pinned_tweet_id", - # "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - "user.fields": "created_at,description" -} - -def user_lookup(url, oauth_params, query_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2UserLookupRuby" - }, - params: query_params - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = user_lookup(user_lookup_url, oauth_params, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Lookup/get_users_with_bearer_token.js b/User-Lookup/get_users_with_bearer_token.js deleted file mode 100644 index 66136a7..0000000 --- a/User-Lookup/get_users_with_bearer_token.js +++ /dev/null @@ -1,53 +0,0 @@ -// Get User objects by username, using bearer token authentication -// https://developer.twitter.com/en/docs/twitter-api/users/lookup/quick-start - -const needle = require('needle'); - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const token = process.env.BEARER_TOKEN; - -const endpointURL = "https://api.twitter.com/2/users/by?usernames=" - -async function getRequest() { - - // These are the parameters for the API request - // specify User names to fetch, and any additional fields that are required - // by default, only the User ID, name and user name are returned - const params = { - usernames: "TwitterDev,TwitterAPI", // Edit usernames to look up - "user.fields": "created_at,description", // Edit optional query parameters here - "expansions": "pinned_tweet_id" - } - - // this is the HTTP header that adds bearer token authentication - const res = await needle('get', endpointURL, params, { - headers: { - "User-Agent": "v2UserLookupJS", - "authorization": `Bearer ${token}` - } - }) - - if (res.body) { - return res.body; - } else { - throw new Error('Unsuccessful request') - } -} - -(async () => { - - try { - // Make request - const response = await getRequest(); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/User-Lookup/get_users_with_bearer_token.r b/User-Lookup/get_users_with_bearer_token.r deleted file mode 100644 index 9585655..0000000 --- a/User-Lookup/get_users_with_bearer_token.r +++ /dev/null @@ -1,20 +0,0 @@ -require(httr) - -bearer_token <- "" - -headers <- c(`Authorization` = sprintf('Bearer %s', bearer_token)) - -params <- list(`user.fields` = 'description') - -handle <- 'TwitterDev' - -url_handle <- - sprintf('https://api.twitter.com/2/users/by?usernames=%s', handle) - -response <- - httr::GET(url = url_handle, - httr::add_headers(.headers = headers), - query = params) - -obj <- httr::content(res, as = "text") -print(obj) diff --git a/User-Lookup/get_users_with_bearer_token.rb b/User-Lookup/get_users_with_bearer_token.rb deleted file mode 100644 index 5386f7e..0000000 --- a/User-Lookup/get_users_with_bearer_token.rb +++ /dev/null @@ -1,44 +0,0 @@ -# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -user_lookup_url = "https://api.twitter.com/2/users" - -# Specify the User IDs that you want to lookup below (to 100 per request) -user_ids = "2244994945,783214" - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs -params = { - "ids": user_ids, - "expansions": "pinned_tweet_id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "name" - # "media.fields": "url", - # "place.fields": "country_code", - # "poll.fields": "options" -} - -def user_lookup(url, bearer_token, params) - options = { - method: 'get', - headers: { - "User-Agent": "v2UserLookupRuby", - "Authorization": "Bearer #{bearer_token}" - }, - params: params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -response = user_lookup(user_lookup_url, bearer_token, params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Lookup/get_users_with_user_context.js b/User-Lookup/get_users_with_user_context.js deleted file mode 100644 index c451c65..0000000 --- a/User-Lookup/get_users_with_user_context.js +++ /dev/null @@ -1,150 +0,0 @@ -// Get User objects by username, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/users/lookup/quick-start - -const got = require('got'); -const crypto = require('crypto'); -const OAuth = require('oauth-1.0a'); -const qs = require('querystring'); -const readline = require('readline').createInterface({ - input: process.stdin, - output: process.stdout -}) - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' -const consumer_key = process.env.CONSUMER_KEY; -const consumer_secret = process.env.CONSUMER_SECRET; - -// These are the parameters for the API request -// specify Tweet IDs to fetch, and any additional fields that are required -// by default, only the Tweet ID and text are returned -const usernames = 'TwitterDev,TwitterAPI' // Edit usernames to look up -const params = 'user.fields=created_at,description&expansions=pinned_tweet_id' // Edit optional query parameters here - -const endpointURL = `https://api.twitter.com/2/users/by?usernames=${usernames}&${params}`; - -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; - -const oauth = OAuth({ - consumer: { - key: consumer_key, - secret: consumer_secret - }, - signature_method: 'HMAC-SHA1', - hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') -}); - -async function input(prompt) { - return new Promise(async (resolve, reject) => { - readline.question(prompt, (out) => { - readline.close(); - resolve(out); - }); - }); -} - -async function requestToken() { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: requestTokenURL, - method: 'POST' - })); - - const req = await got.post(requestTokenURL, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { - - const authHeader = oauth.toHeader(oauth.authorize({ - url: accessTokenURL, - method: 'POST' - })); - - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` - - const req = await got.post(path, { - headers: { - Authorization: authHeader["Authorization"] - } - }); - - if (req.body) { - return qs.parse(req.body); - } else { - throw new Error('Cannot get an OAuth request token'); - } -} - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - - const token = { - key: oauth_token, - secret: oauth_token_secret - }; - - const authHeader = oauth.toHeader(oauth.authorize({ - url: endpointURL, - method: 'GET' - }, token)); - - const req = await got(endpointURL, { - headers: { - Authorization: authHeader["Authorization"], - 'user-agent': "v2UserLookupJS" - } - }); - - if (req.body) { - return JSON.parse(req.body); - } else { - throw new Error('Unsuccessful request'); - } -} - -(async () => { - try { - - // Get request token - const oAuthRequestToken = await requestToken(); - - // Get authorization - authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); - console.log('Please go here and authorize:', authorizeURL.href); - const pin = await input('Paste the PIN here: '); - - // Get the access token - const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); - - } catch (e) { - console.log(e); - process.exit(-1); - } - process.exit(); -})(); diff --git a/User-Lookup/get_users_with_user_context.rb b/User-Lookup/get_users_with_user_context.rb deleted file mode 100644 index 003e630..0000000 --- a/User-Lookup/get_users_with_user_context.rb +++ /dev/null @@ -1,88 +0,0 @@ -# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request -# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) - -require 'oauth' -require 'json' -require 'typhoeus' -require 'oauth/request_proxy/typhoeus_request' - -# The code below sets the consumer key and secret from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' -consumer_key = ENV["CONSUMER_KEY"] -consumer_secret = ENV["CONSUMER_SECRET"] - -# Returns a user object for one or more users specified by the requested usernames -user_lookup_url = "https://api.twitter.com/2/users/by" - -# Specify the usernames that you want to lookup below (to 100 per request) -usernames = "Twitter,TwitterDev" - -consumer = OAuth::Consumer.new(consumer_key, consumer_secret, - :site => 'https://api.twitter.com', - :authorize_path => '/oauth/authenticate', - :debug_output => false) - -def get_request_token(consumer) - - request_token = consumer.get_request_token() - - return request_token -end - -def get_user_authorization(request_token) - puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" - puts "Enter PIN: " - pin = gets.strip - - return pin -end - -def obtain_access_token(consumer, request_token, pin) - token = request_token.token - token_secret = request_token.secret - hash = { :oauth_token => token, :oauth_token_secret => token_secret } - request_token = OAuth::RequestToken.from_hash(consumer, hash) - - # Get access token - access_token = request_token.get_access_token({:oauth_verifier => pin}) - - return access_token -end - -# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: -# https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users -query_params = { - "usernames": usernames, - # "expansions": "pinned_tweet_id", - "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", - # "user.fields": "name" -} - -def user_lookup(url, oauth_params, query_params) - options = { - :method => :get, - headers: { - "User-Agent": "v2UserLookupRuby" - }, - params: query_params - } - request = Typhoeus::Request.new(url, options) - oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) - request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request - response = request.run - - return response -end - -# PIN-based OAuth flow - Step 1 -request_token = get_request_token(consumer) -# PIN-based OAuth flow - Step 2 -pin = get_user_authorization(request_token) -# PIN-based OAuth flow - Step 3 -access_token = obtain_access_token(consumer, request_token, pin) - -oauth_params = {:consumer => consumer, :token => access_token} - -response = user_lookup(user_lookup_url, oauth_params, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Mention-Timeline/UserMentionsDemo.java b/User-Mention-Timeline/UserMentionsDemo.java deleted file mode 100644 index ea36b4a..0000000 --- a/User-Mention-Timeline/UserMentionsDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 User Mentions timeline endpoint - * */ -public class UserMentionsDemo { - - // To set your environment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - //Replace with user ID below - String response = getTweets("2244994945", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 User Mentions timeline endpoint by user ID - * */ - private static String getTweets(String userId, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(String.format("https://api.twitter.com/2/users/%s/mentions", userId)); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} diff --git a/User-Mention-Timeline/user-mentions.rb b/User-Mention-Timeline/user-mentions.rb deleted file mode 100644 index 49274d1..0000000 --- a/User-Mention-Timeline/user-mentions.rb +++ /dev/null @@ -1,49 +0,0 @@ -# This script uses your bearer token to authenticate and make a request to the User mentions timeline endpoint. -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the User mentions timelines. -endpoint_url = "https://api.twitter.com/2/users/:id/mentions" - -# Specify the User ID for this request. -id = 2244994945 #@TwitterDev's numeric User ID. - -# Add or remove parameters below to adjust the query and response fields within the payload -# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ -query_params = { - "max_results" => 100, - # "start_time" => "2020-07-01T00:00:00Z", - # "end_time" => "2020-07-02T18:00:00Z", - "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", - "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", - "user.fields" => "description" - # "media.fields" => "url", - # "place.fields" => "country_code", - # "poll.fields" => "options" -} - -def get_user_mentions(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent" => "v2RubyExampleCode", - "Authorization" => "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -endpoint_url = endpoint_url.gsub(':id',id.to_s()) - -response = get_user_mentions(endpoint_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Mention-Timeline/user_mentions.js b/User-Mention-Timeline/user_mentions.js deleted file mode 100644 index cfd5c08..0000000 --- a/User-Mention-Timeline/user_mentions.js +++ /dev/null @@ -1,74 +0,0 @@ -// Get User mentions timeline by user ID -// https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/quick-start - -const needle = require('needle'); - -const userId = 2244994945; -const url = `https://api.twitter.com/2/users/${userId}/mentions`; - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const bearerToken = process.env.BEARER_TOKEN; - -// this is the ID for @TwitterDev -const getUserMentions = async () => { - let userMentions = []; - let params = { - "max_results": 100, - "tweet.fields": "created_at" - } - - const options = { - headers: { - "User-Agent": "v2UserMentionssJS", - "authorization": `Bearer ${bearerToken}` - } - } - - let hasNextPage = true; - let nextToken = null; - console.log("Retrieving mentions..."); - while (hasNextPage) { - let resp = await getPage(params, options, nextToken); - if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { - if (resp.data) { - userMentions.push.apply(userMentions, resp.data); - } - if (resp.meta.next_token) { - nextToken = resp.meta.next_token; - } else { - hasNextPage = false; - } - } else { - hasNextPage = false; - } - } - - console.dir(userMentions, { - depth: null - }); - - console.log(`Got ${userMentions.length} mentions for user ID ${userId}!`); - -} - -const getPage = async (params, options, nextToken) => { - if (nextToken) { - params.pagination_token = nextToken; - } - - try { - const resp = await needle('get', url, params, options); - - if (resp.statusCode != 200) { - console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); - return; - } - return resp.body; - } catch (err) { - throw new Error(`Request failed: ${err}`); - } -} - -getUserMentions(); diff --git a/User-Tweet-Timeline/UserTweetsDemo.java b/User-Tweet-Timeline/UserTweetsDemo.java deleted file mode 100644 index 19df235..0000000 --- a/User-Tweet-Timeline/UserTweetsDemo.java +++ /dev/null @@ -1,64 +0,0 @@ -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.NameValuePair; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.utils.URIBuilder; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; - -/* - * Sample code to demonstrate the use of the v2 User Tweet timeline endpoint - * */ -public class UserTweetsDemo { - - // To set your environment variables in your terminal run the following line: - // export 'BEARER_TOKEN'='' - - public static void main(String args[]) throws IOException, URISyntaxException { - final String bearerToken = System.getenv("BEARER_TOKEN"); - if (null != bearerToken) { - // Replace with user ID below - String response = getTweets("2244994945", bearerToken); - System.out.println(response); - } else { - System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); - } - } - - /* - * This method calls the v2 User Tweet timeline endpoint by user ID - * */ - private static String getTweets(String userId, String bearerToken) throws IOException, URISyntaxException { - String tweetResponse = null; - - HttpClient httpClient = HttpClients.custom() - .setDefaultRequestConfig(RequestConfig.custom() - .setCookieSpec(CookieSpecs.STANDARD).build()) - .build(); - - URIBuilder uriBuilder = new URIBuilder(String.format("https://api.twitter.com/2/users/%s/tweets", userId)); - ArrayList queryParameters; - queryParameters = new ArrayList<>(); - queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); - uriBuilder.addParameters(queryParameters); - - HttpGet httpGet = new HttpGet(uriBuilder.build()); - httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); - httpGet.setHeader("Content-Type", "application/json"); - - HttpResponse response = httpClient.execute(httpGet); - HttpEntity entity = response.getEntity(); - if (null != entity) { - tweetResponse = EntityUtils.toString(entity, "UTF-8"); - } - return tweetResponse; - } -} diff --git a/User-Tweet-Timeline/user-tweets.rb b/User-Tweet-Timeline/user-tweets.rb deleted file mode 100644 index a652263..0000000 --- a/User-Tweet-Timeline/user-tweets.rb +++ /dev/null @@ -1,55 +0,0 @@ -# This script uses your bearer token to authenticate and make a request to the User Tweets timeline endpoint. - -#Based on recent search example and updated for User mention timeline. -#Next steps: -# [] Refactor for User Tweets timeline.. -# [] Refactor for Full-archive search. - -require 'json' -require 'typhoeus' - -# The code below sets the bearer token from your environment variables -# To set environment variables on Mac OS X, run the export command below from the terminal: -# export BEARER_TOKEN='YOUR-TOKEN' -bearer_token = ENV["BEARER_TOKEN"] - -# Endpoint URL for the Recent Search API -endpoint_url = "https://api.twitter.com/2/users/:id/tweets" - -# Specify the User ID for this request. -id = 2244994945 #@TwitterDev's numeric User ID. - -# Add or remove parameters below to adjust the query and response fields within the payload -# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ -query_params = { - "max_results" => 100, - # "start_time" => "2020-07-01T00:00:00Z", - # "end_time" => "2020-07-02T18:00:00Z", - "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", - "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", - "user.fields" => "description" - # "media.fields" => "url", - # "place.fields" => "country_code", - # "poll.fields" => "options" -} - -def get_user_tweets(url, bearer_token, query_params) - options = { - method: 'get', - headers: { - "User-Agent" => "v2RubyExampleCode", - "Authorization" => "Bearer #{bearer_token}" - }, - params: query_params - } - - request = Typhoeus::Request.new(url, options) - response = request.run - - return response -end - -endpoint_url = endpoint_url.gsub(':id',id.to_s()) - -response = get_user_tweets(endpoint_url, bearer_token, query_params) -puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/User-Tweet-Timeline/user_tweets.js b/User-Tweet-Timeline/user_tweets.js deleted file mode 100644 index 7324d6f..0000000 --- a/User-Tweet-Timeline/user_tweets.js +++ /dev/null @@ -1,79 +0,0 @@ -// Get User Tweet timeline by user ID -// https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/quick-start - -const needle = require('needle'); - -// this is the ID for @TwitterDev -const userId = "2244994945"; -const url = `https://api.twitter.com/2/users/${userId}/tweets`; - -// The code below sets the bearer token from your environment variables -// To set environment variables on macOS or Linux, run the export command below from the terminal: -// export BEARER_TOKEN='YOUR-TOKEN' -const bearerToken = process.env.BEARER_TOKEN; - -const getUserTweets = async () => { - let userTweets = []; - - // we request the author_id expansion so that we can print out the user name later - let params = { - "max_results": 100, - "tweet.fields": "created_at", - "expansions": "author_id" - } - - const options = { - headers: { - "User-Agent": "v2UserTweetsJS", - "authorization": `Bearer ${bearerToken}` - } - } - - let hasNextPage = true; - let nextToken = null; - let userName; - console.log("Retrieving Tweets..."); - - while (hasNextPage) { - let resp = await getPage(params, options, nextToken); - if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { - userName = resp.includes.users[0].username; - if (resp.data) { - userTweets.push.apply(userTweets, resp.data); - } - if (resp.meta.next_token) { - nextToken = resp.meta.next_token; - } else { - hasNextPage = false; - } - } else { - hasNextPage = false; - } - } - - console.dir(userTweets, { - depth: null - }); - console.log(`Got ${userTweets.length} Tweets from ${userName} (user ID ${userId})!`); - -} - -const getPage = async (params, options, nextToken) => { - if (nextToken) { - params.pagination_token = nextToken; - } - - try { - const resp = await needle('get', url, params, options); - - if (resp.statusCode != 200) { - console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); - return; - } - return resp.body; - } catch (err) { - throw new Error(`Request failed: ${err}`); - } -} - -getUserTweets(); diff --git a/User-Tweet-Timeline/user_tweets.py b/User-Tweet-Timeline/user_tweets.py deleted file mode 100644 index 625172c..0000000 --- a/User-Tweet-Timeline/user_tweets.py +++ /dev/null @@ -1,57 +0,0 @@ -import requests -import os -import json - -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' -bearer_token = os.environ.get("BEARER_TOKEN") - - -def create_url(): - # Replace with user ID below - user_id = 2244994945 - return "https://api.twitter.com/2/users/{}/tweets".format(user_id) - - -def get_params(): - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld - return {"tweet.fields": "created_at"} - - -def bearer_oauth(r): - """ - Method required by bearer token authentication. - """ - - r.headers["Authorization"] = f"Bearer {bearer_token}" - r.headers["User-Agent"] = "v2UserTweetsPython" - return r - - -def connect_to_endpoint(url, params): - response = requests.request("GET", url, auth=bearer_oauth, params=params) - print(response.status_code) - if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) - return response.json() - - -def main(): - url = create_url() - params = get_params() - json_response = connect_to_endpoint(url, params) - print(json.dumps(json_response, indent=4, sort_keys=True)) - - -if __name__ == "__main__": - main() diff --git a/api-index.json b/api-index.json new file mode 100644 index 0000000..bd17e8d --- /dev/null +++ b/api-index.json @@ -0,0 +1,489 @@ +{ + "name": "X API v2 Sample Code", + "version": "2.0", + "base_url": "https://api.x.com/2", + "languages": ["python", "javascript", "ruby", "java"], + "endpoints": [ + { + "name": "Create Post", + "path": "/tweets", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "create_post.py", + "javascript": "create_post.js" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets" + }, + { + "name": "Delete Post", + "path": "/tweets/:id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "delete_post.py", + "javascript": "delete_post.js" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id" + }, + { + "name": "Post Lookup", + "path": "/tweets", + "method": "GET", + "auth": ["bearer", "oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "lookup.py", + "javascript": "lookup.js", + "ruby": "lookup.rb" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets" + }, + { + "name": "Recent Search", + "path": "/tweets/search/recent", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "posts", + "files": { + "python": "search_recent.py", + "javascript": "search_recent.js", + "ruby": "search_recent.rb", + "java": "SearchRecent.java" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent" + }, + { + "name": "Full Archive Search", + "path": "/tweets/search/all", + "method": "GET", + "auth": ["bearer"], + "folder": "posts", + "files": { + "python": "search_full_archive.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all", + "note": "Requires Academic Research access" + }, + { + "name": "Recent Post Counts", + "path": "/tweets/counts/recent", + "method": "GET", + "auth": ["bearer"], + "folder": "posts", + "files": { + "python": "counts_recent.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent" + }, + { + "name": "Quote Posts", + "path": "/tweets/:id/quote_tweets", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "posts", + "files": { + "python": "quote_posts.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets" + }, + { + "name": "Repost", + "path": "/users/:id/retweets", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "repost.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets" + }, + { + "name": "Undo Repost", + "path": "/users/:id/retweets/:source_tweet_id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "undo_repost.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id" + }, + { + "name": "Reposted By", + "path": "/tweets/:id/retweeted_by", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "posts", + "files": { + "python": "reposted_by.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/get-tweets-id-retweeted_by" + }, + { + "name": "Like Post", + "path": "/users/:id/likes", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "like.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-id-likes" + }, + { + "name": "Unlike Post", + "path": "/users/:id/likes/:tweet_id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "posts", + "files": { + "python": "unlike.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id" + }, + { + "name": "Liking Users", + "path": "/tweets/:id/liking_users", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "posts", + "files": { + "python": "liking_users.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users" + }, + { + "name": "Liked Posts", + "path": "/users/:id/liked_tweets", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "posts", + "files": { + "python": "liked_posts.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets" + }, + { + "name": "User Lookup", + "path": "/users/by", + "method": "GET", + "auth": ["bearer", "oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "lookup.py", + "javascript": "lookup.js", + "ruby": "lookup.rb", + "java": "Lookup.java" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by" + }, + { + "name": "Authenticated User (Me)", + "path": "/users/me", + "method": "GET", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "me.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me" + }, + { + "name": "User Followers", + "path": "/users/:id/followers", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "users", + "files": { + "python": "followers.py", + "javascript": "followers.js", + "ruby": "followers.rb" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers" + }, + { + "name": "User Following", + "path": "/users/:id/following", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "users", + "files": { + "python": "following.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-following" + }, + { + "name": "Block User", + "path": "/users/:id/blocking", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "block.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking" + }, + { + "name": "Unblock User", + "path": "/users/:source_user_id/blocking/:target_user_id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "unblock.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking" + }, + { + "name": "Blocked Users", + "path": "/users/:id/blocking", + "method": "GET", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "blocked.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking" + }, + { + "name": "Mute User", + "path": "/users/:id/muting", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "mute.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting" + }, + { + "name": "Unmute User", + "path": "/users/:source_user_id/muting/:target_user_id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "unmute.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting" + }, + { + "name": "Muted Users", + "path": "/users/:id/muting", + "method": "GET", + "auth": ["oauth1", "oauth2-user"], + "folder": "users", + "files": { + "python": "muted.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting" + }, + { + "name": "User Posts Timeline", + "path": "/users/:id/tweets", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "timelines", + "files": { + "python": "user_posts.py", + "javascript": "user_posts.js", + "ruby": "user_posts.rb" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets" + }, + { + "name": "User Mentions Timeline", + "path": "/users/:id/mentions", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "timelines", + "files": { + "python": "user_mentions.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions" + }, + { + "name": "Home Timeline", + "path": "/users/:id/reverse_chronological_timeline", + "method": "GET", + "auth": ["oauth1", "oauth2-user"], + "folder": "timelines", + "files": { + "python": "home_timeline.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological-timeline" + }, + { + "name": "Filtered Stream", + "path": "/tweets/search/stream", + "method": "GET", + "auth": ["bearer"], + "folder": "streams", + "files": { + "python": "filtered_stream.py", + "javascript": "filtered_stream.js" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream" + }, + { + "name": "Sampled Stream", + "path": "/tweets/sample/stream", + "method": "GET", + "auth": ["bearer"], + "folder": "streams", + "files": { + "python": "sampled_stream.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream" + }, + { + "name": "Bookmarks Lookup", + "path": "/users/:id/bookmarks", + "method": "GET", + "auth": ["oauth2-user"], + "folder": "bookmarks", + "files": { + "python": "lookup.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks" + }, + { + "name": "Create Bookmark", + "path": "/users/:id/bookmarks", + "method": "POST", + "auth": ["oauth2-user"], + "folder": "bookmarks", + "files": { + "python": "create.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks" + }, + { + "name": "Delete Bookmark", + "path": "/users/:id/bookmarks/:tweet_id", + "method": "DELETE", + "auth": ["oauth2-user"], + "folder": "bookmarks", + "files": { + "python": "delete.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id" + }, + { + "name": "Spaces Lookup", + "path": "/spaces", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "spaces", + "files": { + "python": "lookup.py", + "javascript": "lookup.js" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces" + }, + { + "name": "Spaces Search", + "path": "/spaces/search", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "spaces", + "files": { + "python": "search.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search" + }, + { + "name": "List Lookup", + "path": "/lists/:id", + "method": "GET", + "auth": ["bearer", "oauth2-user"], + "folder": "lists", + "files": { + "python": "lookup.py", + "javascript": "lookup.js", + "ruby": "lookup.rb" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id" + }, + { + "name": "Create List", + "path": "/lists", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "lists", + "files": { + "python": "create.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists" + }, + { + "name": "Delete List", + "path": "/lists/:id", + "method": "DELETE", + "auth": ["oauth1", "oauth2-user"], + "folder": "lists", + "files": { + "python": "delete.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id" + }, + { + "name": "DM Events Lookup", + "path": "/dm_events", + "method": "GET", + "auth": ["oauth1", "oauth2-user"], + "folder": "direct_messages", + "files": { + "python": "lookup.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm-events" + }, + { + "name": "Send DM", + "path": "/dm_conversations/with/:participant_id/messages", + "method": "POST", + "auth": ["oauth1", "oauth2-user"], + "folder": "direct_messages", + "files": { + "python": "send.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm-conversations-with-participant_id-messages" + }, + { + "name": "Create Compliance Job", + "path": "/compliance/jobs", + "method": "POST", + "auth": ["bearer"], + "folder": "compliance", + "files": { + "python": "create_job.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs" + }, + { + "name": "Get Compliance Jobs", + "path": "/compliance/jobs", + "method": "GET", + "auth": ["bearer"], + "folder": "compliance", + "files": { + "python": "get_jobs.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs" + }, + { + "name": "API Usage", + "path": "/usage/tweets", + "method": "GET", + "auth": ["bearer"], + "folder": "usage", + "files": { + "python": "get_usage.py" + }, + "docs": "https://developer.x.com/en/docs/twitter-api/usage/api-reference/get-usage-tweets" + } + ] +} diff --git a/java/README.md b/java/README.md new file mode 100644 index 0000000..44fbe43 --- /dev/null +++ b/java/README.md @@ -0,0 +1,64 @@ +# X API v2 - Java Examples + +Working Java code samples for the X (formerly Twitter) API v2. + +## Setup + +### 1. Install Java 11+ + +```bash +java --version +``` + +### 2. Add dependencies + +Using Maven, add to your `pom.xml`: + +```xml + + + org.apache.httpcomponents + httpclient + 4.5.13 + + + com.google.code.gson + gson + 2.9.1 + + +``` + +### 3. Set environment variables + +For **Bearer Token** authentication (app-only): +```bash +export BEARER_TOKEN='your_bearer_token' +``` + +## Examples by Category + +### Posts +| File | Description | Auth | +|------|-------------|------| +| `posts/SearchRecent.java` | Search recent posts (7 days) | Bearer | + +### Users +| File | Description | Auth | +|------|-------------|------| +| `users/Lookup.java` | Look up users by username | Bearer | + +## Building and Running + +```bash +# Compile +javac -cp ".:lib/*" posts/SearchRecent.java + +# Run +java -cp ".:lib/*" SearchRecent +``` + +## More Information + +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [X Developer Portal](https://developer.x.com/en/portal/dashboard) diff --git a/java/posts/SearchRecent.java b/java/posts/SearchRecent.java new file mode 100644 index 0000000..9540c56 --- /dev/null +++ b/java/posts/SearchRecent.java @@ -0,0 +1,64 @@ +/** + * Recent Search - X API v2 + * + * Endpoint: GET https://api.x.com/2/tweets/search/recent + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent + * + * Authentication: Bearer Token (App-only) + * Required env vars: BEARER_TOKEN + * + * Dependencies: org.apache.httpcomponents:httpclient, com.google.code.gson:gson + */ + +import java.io.IOException; +import java.net.URISyntaxException; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +public class SearchRecent { + + public static void main(String[] args) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + + if (bearerToken == null) { + System.err.println("BEARER_TOKEN environment variable not set"); + System.exit(1); + } + + String response = search("from:XDevelopers -is:retweet", bearerToken); + System.out.println(response); + } + + private static String search(String query, String bearerToken) throws IOException, URISyntaxException { + String searchUrl = "https://api.x.com/2/tweets/search/recent"; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(searchUrl); + uriBuilder.addParameter("query", query); + uriBuilder.addParameter("tweet.fields", "author_id,created_at"); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", "Bearer " + bearerToken); + httpGet.setHeader("User-Agent", "v2RecentSearchJava"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + + if (entity != null) { + return EntityUtils.toString(entity, "UTF-8"); + } else { + return "No response"; + } + } +} diff --git a/java/users/Lookup.java b/java/users/Lookup.java new file mode 100644 index 0000000..ff0d781 --- /dev/null +++ b/java/users/Lookup.java @@ -0,0 +1,64 @@ +/** + * User Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/users/by + * Docs: https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * Authentication: Bearer Token (App-only) + * Required env vars: BEARER_TOKEN + * + * Dependencies: org.apache.httpcomponents:httpclient, com.google.code.gson:gson + */ + +import java.io.IOException; +import java.net.URISyntaxException; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +public class Lookup { + + public static void main(String[] args) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + + if (bearerToken == null) { + System.err.println("BEARER_TOKEN environment variable not set"); + System.exit(1); + } + + String response = lookupUsers("XDevelopers,X", bearerToken); + System.out.println(response); + } + + private static String lookupUsers(String usernames, String bearerToken) throws IOException, URISyntaxException { + String userLookupUrl = "https://api.x.com/2/users/by"; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(userLookupUrl); + uriBuilder.addParameter("usernames", usernames); + uriBuilder.addParameter("user.fields", "created_at,description,public_metrics"); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", "Bearer " + bearerToken); + httpGet.setHeader("User-Agent", "v2UserLookupJava"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + + if (entity != null) { + return EntityUtils.toString(entity, "UTF-8"); + } else { + return "No response"; + } + } +} diff --git a/javascript/README.md b/javascript/README.md new file mode 100644 index 0000000..216afe5 --- /dev/null +++ b/javascript/README.md @@ -0,0 +1,78 @@ +# X API v2 - JavaScript (Node.js) Examples + +Working JavaScript code samples for the X (formerly Twitter) API v2. + +## Setup + +### 1. Install Node.js 14+ + +```bash +node --version +``` + +### 2. Install dependencies + +```bash +npm install +``` + +### 3. Set environment variables + +For **Bearer Token** authentication (app-only): +```bash +export BEARER_TOKEN='your_bearer_token' +``` + +For **OAuth 1.0a** authentication (user context): +```bash +export CONSUMER_KEY='your_consumer_key' +export CONSUMER_SECRET='your_consumer_secret' +``` + +## Examples by Category + +### Posts +| File | Description | Auth | +|------|-------------|------| +| `posts/create_post.js` | Create a new post | OAuth 1.0a | +| `posts/delete_post.js` | Delete a post | OAuth 1.0a | +| `posts/lookup.js` | Look up posts by ID | Bearer | +| `posts/search_recent.js` | Search recent posts (7 days) | Bearer | + +### Users +| File | Description | Auth | +|------|-------------|------| +| `users/lookup.js` | Look up users by username | Bearer | +| `users/followers.js` | Get user's followers | Bearer | + +### Timelines +| File | Description | Auth | +|------|-------------|------| +| `timelines/user_posts.js` | User's posts timeline | Bearer | + +### Streams +| File | Description | Auth | +|------|-------------|------| +| `streams/filtered_stream.js` | Filtered stream with rules | Bearer | + +### Lists +| File | Description | Auth | +|------|-------------|------| +| `lists/lookup.js` | Look up a list | Bearer | + +### Spaces +| File | Description | Auth | +|------|-------------|------| +| `spaces/lookup.js` | Look up Spaces | Bearer | + +## Running Examples + +```bash +# Make sure environment variables are set +node posts/search_recent.js +``` + +## More Information + +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [X Developer Portal](https://developer.x.com/en/portal/dashboard) diff --git a/javascript/lists/lookup.js b/javascript/lists/lookup.js new file mode 100644 index 0000000..868e8d3 --- /dev/null +++ b/javascript/lists/lookup.js @@ -0,0 +1,47 @@ +/** + * List Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/lists/:id + * Docs: https://developer.x.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; + +// Replace with the list ID you want to look up +const listId = "84839422"; +const endpointURL = `https://api.x.com/2/lists/${listId}`; + +async function getRequest() { + const params = { + "list.fields": "created_at,follower_count,member_count,owner_id,description" + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2ListLookupJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/Manage-Tweets/create_tweet.js b/javascript/posts/create_post.js similarity index 67% rename from Manage-Tweets/create_tweet.js rename to javascript/posts/create_post.js index 64de55a..956efd1 100644 --- a/Manage-Tweets/create_tweet.js +++ b/javascript/posts/create_post.js @@ -1,34 +1,36 @@ +/** + * Create Post - X API v2 + * + * Endpoint: POST https://api.x.com/2/tweets + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + * + * Authentication: OAuth 1.0a (User Context) + * Required env vars: CONSUMER_KEY, CONSUMER_SECRET + */ + const got = require('got'); const crypto = require('crypto'); const OAuth = require('oauth-1.0a'); const qs = require('querystring'); - const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout }); - -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' const consumer_key = process.env.CONSUMER_KEY; const consumer_secret = process.env.CONSUMER_SECRET; - -// Be sure to add replace the text of the with the text you wish to Tweet. -// You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. +// The text content of the post. You can also add parameters for polls, +// quote posts, reply settings, and more. const data = { "text": "Hello world!" }; -const endpointURL = `https://api.twitter.com/2/tweets`; +const endpointURL = 'https://api.x.com/2/tweets'; +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; const oauth = OAuth({ consumer: { key: consumer_key, @@ -65,16 +67,12 @@ async function requestToken() { } } - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { const authHeader = oauth.toHeader(oauth.authorize({ url: accessTokenURL, method: 'POST' })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; const req = await got.post(path, { headers: { Authorization: authHeader["Authorization"] @@ -87,12 +85,7 @@ async function accessToken({ } } - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - +async function createPost({ oauth_token, oauth_token_secret }) { const token = { key: oauth_token, secret: oauth_token_secret @@ -108,7 +101,7 @@ async function getRequest({ responseType: 'json', headers: { Authorization: authHeader["Authorization"], - 'user-agent': "v2CreateTweetJS", + 'user-agent': "v2CreatePostJS", 'content-type': "application/json", 'accept': "application/json" } @@ -120,7 +113,6 @@ async function getRequest({ } } - (async () => { try { // Get request token @@ -132,10 +124,8 @@ async function getRequest({ // Get the access token const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); + const response = await createPost(oAuthAccessToken); + console.dir(response, { depth: null }); } catch (e) { console.log(e); process.exit(-1); diff --git a/Blocks-Lookup/lookup_blocks.js b/javascript/posts/delete_post.js similarity index 60% rename from Blocks-Lookup/lookup_blocks.js rename to javascript/posts/delete_post.js index a29bc0c..3d36b84 100644 --- a/Blocks-Lookup/lookup_blocks.js +++ b/javascript/posts/delete_post.js @@ -1,33 +1,33 @@ -// Block a user, using user authentication -// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start +/** + * Delete Post - X API v2 + * + * Endpoint: DELETE https://api.x.com/2/tweets/:id + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + * + * Authentication: OAuth 1.0a (User Context) + * Required env vars: CONSUMER_KEY, CONSUMER_SECRET + */ + const got = require('got'); const crypto = require('crypto'); const OAuth = require('oauth-1.0a'); const qs = require('querystring'); - const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout -}) - +}); -// The code below sets the consumer key and consumer secret from your environment variables -// To set environment variables on macOS or Linux, run the export commands below from the terminal: -// export CONSUMER_KEY='YOUR-KEY' -// export CONSUMER_SECRET='YOUR-SECRET' const consumer_key = process.env.CONSUMER_KEY; const consumer_secret = process.env.CONSUMER_SECRET; +// Replace with the post ID you want to delete +const postId = "post-id-to-delete"; +const endpointURL = `https://api.x.com/2/tweets/${postId}`; -// Be sure to replace your-user-id with your own user ID or one of an authenticated user -// You can find a user ID by using the user lookup endpoint -const id = "your-user-id"; -const endpointURL = `https://api.twitter.com/2/users/${id}/blocking`; +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; -// this example uses PIN-based OAuth to authorize the user -const requestTokenURL = 'https://api.twitter.com/oauth/request_token?oauth_callback=oob'; -const authorizeURL = new URL('https://api.twitter.com/oauth/authorize'); -const accessTokenURL = 'https://api.twitter.com/oauth/access_token'; const oauth = OAuth({ consumer: { key: consumer_key, @@ -64,16 +64,12 @@ async function requestToken() { } } - -async function accessToken({ - oauth_token, - oauth_token_secret -}, verifier) { +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { const authHeader = oauth.toHeader(oauth.authorize({ url: accessTokenURL, method: 'POST' })); - const path = `https://api.twitter.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; const req = await got.post(path, { headers: { Authorization: authHeader["Authorization"] @@ -86,12 +82,7 @@ async function accessToken({ } } - -async function getRequest({ - oauth_token, - oauth_token_secret -}) { - +async function deletePost({ oauth_token, oauth_token_secret }) { const token = { key: oauth_token, secret: oauth_token_secret @@ -99,14 +90,14 @@ async function getRequest({ const authHeader = oauth.toHeader(oauth.authorize({ url: endpointURL, - method: 'GET' + method: 'DELETE' }, token)); - const req = await got.get(endpointURL, { + const req = await got.delete(endpointURL, { responseType: 'json', headers: { Authorization: authHeader["Authorization"], - 'user-agent': "v2BlocksLookupJS" + 'user-agent': "v2DeletePostJS" } }); if (req.body) { @@ -116,22 +107,15 @@ async function getRequest({ } } - (async () => { try { - // Get request token const oAuthRequestToken = await requestToken(); - // Get authorization authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); console.log('Please go here and authorize:', authorizeURL.href); const pin = await input('Paste the PIN here: '); - // Get the access token const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); - // Make the request - const response = await getRequest(oAuthAccessToken); - console.dir(response, { - depth: null - }); + const response = await deletePost(oAuthAccessToken); + console.dir(response, { depth: null }); } catch (e) { console.log(e); process.exit(-1); diff --git a/javascript/posts/lookup.js b/javascript/posts/lookup.js new file mode 100644 index 0000000..51f7880 --- /dev/null +++ b/javascript/posts/lookup.js @@ -0,0 +1,47 @@ +/** + * Post Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/tweets + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; +const endpointURL = "https://api.x.com/2/tweets"; + +async function getRequest() { + // Post IDs to look up (comma-separated, up to 100) + const params = { + "ids": "1278747501642657792,1255542774432063488", + "tweet.fields": "created_at,author_id,lang,source,public_metrics", + "expansions": "author_id" + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2PostLookupJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/search_recent.js b/javascript/posts/search_recent.js new file mode 100644 index 0000000..1315dc2 --- /dev/null +++ b/javascript/posts/search_recent.js @@ -0,0 +1,49 @@ +/** + * Recent Search - X API v2 + * + * Endpoint: GET https://api.x.com/2/tweets/search/recent + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent + * + * Authentication: Bearer Token (App-only) + * Required env vars: BEARER_TOKEN + * + * Note: Returns posts from the last 7 days. + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; +const endpointUrl = "https://api.x.com/2/tweets/search/recent"; + +async function getRequest() { + // Edit query parameters below + // By default, only the post ID and text fields are returned + const params = { + 'query': 'from:XDevelopers -is:retweet', + 'tweet.fields': 'author_id,created_at' + }; + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2RecentSearchJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/spaces/lookup.js b/javascript/spaces/lookup.js new file mode 100644 index 0000000..6d8b2a6 --- /dev/null +++ b/javascript/spaces/lookup.js @@ -0,0 +1,45 @@ +/** + * Spaces Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/spaces + * Docs: https://developer.x.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; +const endpointURL = "https://api.x.com/2/spaces"; + +async function getRequest() { + const params = { + "ids": "1DXxyRYNejbKM", + "space.fields": "host_ids,created_at,creator_id,participant_count,title,state" + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2SpacesLookupJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/streams/filtered_stream.js b/javascript/streams/filtered_stream.js new file mode 100644 index 0000000..5fd747a --- /dev/null +++ b/javascript/streams/filtered_stream.js @@ -0,0 +1,130 @@ +/** + * Filtered Stream - X API v2 + * + * Endpoint: GET https://api.x.com/2/tweets/search/stream + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream + * + * Authentication: Bearer Token (App-only) + * Required env vars: BEARER_TOKEN + * + * This example demonstrates: + * 1. Getting existing rules + * 2. Deleting all existing rules + * 3. Setting new rules + * 4. Connecting to the stream + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; +const rulesURL = 'https://api.x.com/2/tweets/search/stream/rules'; +const streamURL = 'https://api.x.com/2/tweets/search/stream'; + +// Adjust rules as needed +const rules = [ + { 'value': 'dog has:images', 'tag': 'dog pictures' }, + { 'value': 'cat has:images -grumpy', 'tag': 'cat pictures' }, +]; + +async function getAllRules() { + const response = await needle('get', rulesURL, { + headers: { + "authorization": `Bearer ${token}` + } + }); + + if (response.statusCode !== 200) { + throw new Error(`Error getting rules: ${response.body}`); + } + + return response.body; +} + +async function deleteAllRules(rules) { + if (!Array.isArray(rules.data)) { + return null; + } + + const ids = rules.data.map(rule => rule.id); + const data = { "delete": { "ids": ids } }; + + const response = await needle('post', rulesURL, data, { + headers: { + "content-type": "application/json", + "authorization": `Bearer ${token}` + } + }); + + if (response.statusCode !== 200) { + throw new Error(`Error deleting rules: ${response.body}`); + } + + return response.body; +} + +async function setRules() { + const data = { "add": rules }; + + const response = await needle('post', rulesURL, data, { + headers: { + "content-type": "application/json", + "authorization": `Bearer ${token}` + } + }); + + if (response.statusCode !== 201) { + throw new Error(`Error setting rules: ${response.body}`); + } + + return response.body; +} + +function streamConnect() { + const stream = needle.get(streamURL, { + headers: { + "User-Agent": "v2FilteredStreamJS", + "Authorization": `Bearer ${token}` + }, + timeout: 20000 + }); + + stream.on('data', data => { + try { + const json = JSON.parse(data); + console.log(json); + } catch (e) { + // Keep alive signal received + } + }); + + stream.on('error', error => { + if (error.code === 'ETIMEDOUT') { + stream.emit('timeout'); + } + }); + + return stream; +} + +(async () => { + try { + // Get all stream rules + let currentRules = await getAllRules(); + console.log("Current rules:", currentRules); + + // Delete all stream rules + await deleteAllRules(currentRules); + console.log("Deleted existing rules"); + + // Set new rules + await setRules(); + console.log("Set new rules"); + + // Connect to the stream + console.log("Connecting to stream..."); + streamConnect(); + } catch (e) { + console.error(e); + process.exit(-1); + } +})(); diff --git a/javascript/timelines/user_posts.js b/javascript/timelines/user_posts.js new file mode 100644 index 0000000..100f443 --- /dev/null +++ b/javascript/timelines/user_posts.js @@ -0,0 +1,48 @@ +/** + * User Posts Timeline - X API v2 + * + * Endpoint: GET https://api.x.com/2/users/:id/tweets + * Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; + +// Replace with the user ID you want to get posts for +const userId = "2244994945"; +const endpointURL = `https://api.x.com/2/users/${userId}/tweets`; + +async function getRequest() { + const params = { + "tweet.fields": "created_at,public_metrics", + "max_results": 10 + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2UserPostsJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/followers.js b/javascript/users/followers.js new file mode 100644 index 0000000..7605b47 --- /dev/null +++ b/javascript/users/followers.js @@ -0,0 +1,48 @@ +/** + * User Followers Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/users/:id/followers + * Docs: https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; + +// Replace with the user ID you want to get followers for +const userId = "2244994945"; +const endpointURL = `https://api.x.com/2/users/${userId}/followers`; + +async function getRequest() { + const params = { + "user.fields": "created_at,description", + "max_results": 100 + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2FollowersJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/lookup.js b/javascript/users/lookup.js new file mode 100644 index 0000000..3cfbed9 --- /dev/null +++ b/javascript/users/lookup.js @@ -0,0 +1,46 @@ +/** + * User Lookup - X API v2 + * + * Endpoint: GET https://api.x.com/2/users/by + * Docs: https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + * + * Authentication: Bearer Token (App-only) or OAuth (User Context) + * Required env vars: BEARER_TOKEN + */ + +const needle = require('needle'); + +const token = process.env.BEARER_TOKEN; +const endpointURL = "https://api.x.com/2/users/by"; + +async function getRequest() { + // Usernames to look up (up to 100 comma-separated) + const params = { + "usernames": "XDevelopers,X", + "user.fields": "created_at,description,public_metrics" + }; + + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2UserLookupJS", + "authorization": `Bearer ${token}` + } + }); + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + const response = await getRequest(); + console.dir(response, { depth: null }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/llms.txt b/llms.txt new file mode 100644 index 0000000..254197a --- /dev/null +++ b/llms.txt @@ -0,0 +1,156 @@ +# X API v2 Sample Code Repository + +> This file provides context for LLMs (Large Language Models) to understand and navigate this codebase. + +## Purpose + +This repository contains working code examples for the X (formerly Twitter) API v2. Examples are provided in Python, JavaScript (Node.js), Ruby, and Java. + +## Repository Structure + +``` +/ +├── python/ # Python examples +│ ├── posts/ # Create, delete, search, lookup posts +│ ├── users/ # User lookup, followers, blocks, mutes +│ ├── timelines/ # User posts, mentions, home timeline +│ ├── streams/ # Filtered and sampled streams +│ ├── bookmarks/ # Bookmark management +│ ├── spaces/ # Spaces lookup and search +│ ├── lists/ # List management +│ ├── direct_messages/ # DM lookup and sending +│ ├── media/ # Media upload +│ ├── compliance/ # Batch compliance jobs +│ └── usage/ # API usage stats +├── javascript/ # JavaScript (Node.js) examples +├── ruby/ # Ruby examples +├── java/ # Java examples +└── docs/ # Endpoint documentation (language-agnostic) +``` + +## File Naming Conventions + +- Python: `snake_case.py` (e.g., `create_post.py`) +- JavaScript: `snake_case.js` (e.g., `create_post.js`) +- Ruby: `snake_case.rb` (e.g., `search_recent.rb`) +- Java: `PascalCase.java` (e.g., `SearchRecent.java`) + +## Authentication Types + +1. **Bearer Token** (App-only): For read-only endpoints that don't require user context + - Env var: `BEARER_TOKEN` + +2. **OAuth 1.0a** (User Context): For endpoints that act on behalf of a user + - Env vars: `CONSUMER_KEY`, `CONSUMER_SECRET` + +3. **OAuth 2.0 with PKCE** (User Context): For newer endpoints like bookmarks + - Requires OAuth 2.0 flow to get user access token + +## API Base URL + +All endpoints use: `https://api.x.com/2/` + +## Key Terminology (Rebrand) + +| Old Term | New Term | +|----------|----------| +| Tweet | Post | +| Retweet | Repost | +| Twitter | X | +| TwitterDev | XDevelopers | + +Note: The API endpoints still use `/tweets/` in the URL path for backwards compatibility. + +## Common Operations by Category + +### Posts (formerly Tweets) +- `POST /2/tweets` - Create a post +- `DELETE /2/tweets/:id` - Delete a post +- `GET /2/tweets` - Look up posts by ID +- `GET /2/tweets/search/recent` - Search recent posts (7 days) +- `GET /2/tweets/search/all` - Search all posts (Academic access) +- `GET /2/tweets/counts/recent` - Count recent posts +- `GET /2/tweets/:id/quote_tweets` - Get quote posts +- `POST /2/users/:id/retweets` - Repost +- `DELETE /2/users/:id/retweets/:tweet_id` - Undo repost + +### Users +- `GET /2/users/by` - Look up users by username +- `GET /2/users/me` - Get authenticated user +- `GET /2/users/:id/followers` - Get followers +- `GET /2/users/:id/following` - Get following +- `POST /2/users/:id/blocking` - Block user +- `POST /2/users/:id/muting` - Mute user + +### Timelines +- `GET /2/users/:id/tweets` - User's posts +- `GET /2/users/:id/mentions` - User's mentions +- `GET /2/users/:id/reverse_chronological_timeline` - Home timeline + +### Streams (Real-time) +- `GET /2/tweets/search/stream` - Filtered stream +- `GET /2/tweets/sample/stream` - 1% sampled stream + +### Likes +- `POST /2/users/:id/likes` - Like a post +- `DELETE /2/users/:id/likes/:tweet_id` - Unlike a post +- `GET /2/tweets/:id/liking_users` - Users who liked +- `GET /2/users/:id/liked_tweets` - Posts user liked + +### Bookmarks +- `GET /2/users/:id/bookmarks` - Get bookmarks +- `POST /2/users/:id/bookmarks` - Create bookmark +- `DELETE /2/users/:id/bookmarks/:tweet_id` - Delete bookmark + +### Lists +- `GET /2/lists/:id` - Look up list +- `POST /2/lists` - Create list +- `DELETE /2/lists/:id` - Delete list + +### Spaces +- `GET /2/spaces` - Look up Spaces by ID +- `GET /2/spaces/search` - Search Spaces + +### Direct Messages +- `GET /2/dm_events` - Get DM events +- `POST /2/dm_conversations/with/:participant_id/messages` - Send DM + +## Quick Start + +1. Get API credentials at https://developer.x.com/portal +2. Set environment variables: + ```bash + export BEARER_TOKEN='your_token' + export CONSUMER_KEY='your_key' + export CONSUMER_SECRET='your_secret' + ``` +3. Navigate to desired language folder +4. Install dependencies (see language-specific README) +5. Run example + +## Dependencies by Language + +### Python +```bash +pip install requests requests-oauthlib +``` + +### JavaScript +```bash +npm install needle got oauth-1.0a +``` + +### Ruby +```bash +gem install typhoeus oauth +``` + +### Java +- Apache HttpClient 4.5+ +- Gson 2.9+ + +## External Resources + +- API Documentation: https://developer.x.com/en/docs/twitter-api +- Developer Portal: https://developer.x.com/en/portal/dashboard +- API Reference: https://developer.x.com/en/docs/api-reference-index diff --git a/python/README.md b/python/README.md new file mode 100644 index 0000000..7048b2c --- /dev/null +++ b/python/README.md @@ -0,0 +1,139 @@ +# X API v2 - Python Examples + +Working Python code samples for the X (formerly Twitter) API v2. + +## Setup + +### 1. Install Python 3.7+ + +```bash +python3 --version +``` + +### 2. Create a virtual environment (recommended) + +```bash +python3 -m venv venv +source venv/bin/activate # On Windows: venv\Scripts\activate +``` + +### 3. Install dependencies + +```bash +pip install -r requirements.txt +``` + +### 4. Set environment variables + +For **Bearer Token** authentication (app-only): +```bash +export BEARER_TOKEN='your_bearer_token' +``` + +For **OAuth 1.0a** authentication (user context): +```bash +export CONSUMER_KEY='your_consumer_key' +export CONSUMER_SECRET='your_consumer_secret' +``` + +## Examples by Category + +### Posts (Tweets) +| File | Description | Auth | +|------|-------------|------| +| `posts/create_post.py` | Create a new post | OAuth 1.0a | +| `posts/delete_post.py` | Delete a post | OAuth 1.0a | +| `posts/lookup.py` | Look up posts by ID | Bearer | +| `posts/search_recent.py` | Search recent posts (7 days) | Bearer | +| `posts/search_full_archive.py` | Search all posts (Academic) | Bearer | +| `posts/counts_recent.py` | Get post counts (7 days) | Bearer | +| `posts/counts_full_archive.py` | Get post counts (all time) | Bearer | +| `posts/quote_posts.py` | Get quote posts | Bearer | +| `posts/repost.py` | Repost (retweet) | OAuth 1.0a | +| `posts/undo_repost.py` | Undo repost | OAuth 1.0a | +| `posts/reposted_by.py` | Users who reposted | Bearer | +| `posts/like.py` | Like a post | OAuth 1.0a | +| `posts/unlike.py` | Unlike a post | OAuth 1.0a | +| `posts/liking_users.py` | Users who liked a post | Bearer | +| `posts/liked_posts.py` | Posts liked by a user | Bearer | + +### Users +| File | Description | Auth | +|------|-------------|------| +| `users/lookup.py` | Look up users by username | Bearer | +| `users/me.py` | Get authenticated user | OAuth 1.0a | +| `users/followers.py` | Get user's followers | Bearer | +| `users/following.py` | Get user's following | Bearer | +| `users/block.py` | Block a user | OAuth 1.0a | +| `users/unblock.py` | Unblock a user | OAuth 1.0a | +| `users/blocked.py` | Get blocked users | OAuth 1.0a | +| `users/mute.py` | Mute a user | OAuth 1.0a | +| `users/unmute.py` | Unmute a user | OAuth 1.0a | +| `users/muted.py` | Get muted users | OAuth 1.0a | + +### Timelines +| File | Description | Auth | +|------|-------------|------| +| `timelines/user_posts.py` | User's posts timeline | Bearer | +| `timelines/user_mentions.py` | User's mentions | Bearer | +| `timelines/home_timeline.py` | Home timeline | OAuth 1.0a | + +### Streams +| File | Description | Auth | +|------|-------------|------| +| `streams/filtered_stream.py` | Filtered stream with rules | Bearer | +| `streams/sampled_stream.py` | 1% sampled stream | Bearer | + +### Bookmarks +| File | Description | Auth | +|------|-------------|------| +| `bookmarks/lookup.py` | Get bookmarks | OAuth 2.0 | +| `bookmarks/create.py` | Create bookmark | OAuth 2.0 | +| `bookmarks/delete.py` | Delete bookmark | OAuth 2.0 | + +### Spaces +| File | Description | Auth | +|------|-------------|------| +| `spaces/lookup.py` | Look up Spaces | Bearer | +| `spaces/search.py` | Search Spaces | Bearer | + +### Lists +| File | Description | Auth | +|------|-------------|------| +| `lists/lookup.py` | Look up a list | Bearer | +| `lists/create.py` | Create a list | OAuth 1.0a | +| `lists/delete.py` | Delete a list | OAuth 1.0a | + +### Direct Messages +| File | Description | Auth | +|------|-------------|------| +| `direct_messages/lookup.py` | Get DM events | OAuth 1.0a | +| `direct_messages/send.py` | Send a DM | OAuth 1.0a | + +### Media +| File | Description | Auth | +|------|-------------|------| +| `media/upload.py` | Upload media | OAuth 1.0a | + +### Compliance +| File | Description | Auth | +|------|-------------|------| +| `compliance/create_job.py` | Create compliance job | Bearer | +| `compliance/get_jobs.py` | Get compliance jobs | Bearer | + +### Usage +| File | Description | Auth | +|------|-------------|------| +| `usage/get_usage.py` | Get API usage stats | Bearer | + +## Running Examples + +```bash +# Make sure environment variables are set +python posts/search_recent.py +``` + +## More Information + +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [X Developer Portal](https://developer.x.com/en/portal/dashboard) diff --git a/python/bookmarks/create.py b/python/bookmarks/create.py new file mode 100644 index 0000000..0499013 --- /dev/null +++ b/python/bookmarks/create.py @@ -0,0 +1,54 @@ +""" +Create Bookmark - X API v2 +========================== +Endpoint: POST https://api.x.com/2/users/:id/bookmarks +Docs: https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/post-users-id-bookmarks + +Authentication: OAuth 2.0 with PKCE (User Context) +Required env vars: BEARER_TOKEN (OAuth 2.0 user access token) +""" + +import requests +import os +import json + +# Note: This endpoint requires OAuth 2.0 User Context +# The bearer_token here should be the user's access token from OAuth 2.0 PKCE flow +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(user_id): + return "https://api.x.com/2/users/{}/bookmarks".format(user_id) + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2CreateBookmarkPython" + return r + + +def connect_to_endpoint(url, payload): + response = requests.post(url, auth=bearer_oauth, json=payload) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + # Replace with the authenticated user's ID + user_id = "your-user-id" + + # Replace with the post ID you want to bookmark + payload = {"tweet_id": "post-id-to-bookmark"} + + url = create_url(user_id) + json_response = connect_to_endpoint(url, payload) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/bookmarks/delete.py b/python/bookmarks/delete.py new file mode 100644 index 0000000..d962f16 --- /dev/null +++ b/python/bookmarks/delete.py @@ -0,0 +1,54 @@ +""" +Delete Bookmark - X API v2 +========================== +Endpoint: DELETE https://api.x.com/2/users/:id/bookmarks/:tweet_id +Docs: https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/delete-users-id-bookmarks-tweet_id + +Authentication: OAuth 2.0 with PKCE (User Context) +Required env vars: BEARER_TOKEN (OAuth 2.0 user access token) +""" + +import requests +import os +import json + +# Note: This endpoint requires OAuth 2.0 User Context +# The bearer_token here should be the user's access token from OAuth 2.0 PKCE flow +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(user_id, post_id): + return "https://api.x.com/2/users/{}/bookmarks/{}".format(user_id, post_id) + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2DeleteBookmarkPython" + return r + + +def connect_to_endpoint(url): + response = requests.delete(url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + # Replace with the authenticated user's ID + user_id = "your-user-id" + + # Replace with the post ID you want to remove from bookmarks + post_id = "post-id-to-unbookmark" + + url = create_url(user_id, post_id) + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/bookmarks/lookup.py b/python/bookmarks/lookup.py new file mode 100644 index 0000000..6af4463 --- /dev/null +++ b/python/bookmarks/lookup.py @@ -0,0 +1,55 @@ +""" +Bookmarks Lookup - X API v2 +=========================== +Endpoint: GET https://api.x.com/2/users/:id/bookmarks +Docs: https://developer.x.com/en/docs/twitter-api/tweets/bookmarks/api-reference/get-users-id-bookmarks + +Authentication: OAuth 2.0 with PKCE (User Context) +Required env vars: BEARER_TOKEN (OAuth 2.0 user access token) +""" + +import requests +import os +import json + +# Note: This endpoint requires OAuth 2.0 User Context +# The bearer_token here should be the user's access token from OAuth 2.0 PKCE flow +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(user_id): + return "https://api.x.com/2/users/{}/bookmarks".format(user_id) + + +def get_params(): + return {"tweet.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2BookmarksLookupPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + # Replace with the authenticated user's ID + user_id = "your-user-id" + url = create_url(user_id) + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/compliance/create_job.py b/python/compliance/create_job.py new file mode 100644 index 0000000..ba7ce03 --- /dev/null +++ b/python/compliance/create_job.py @@ -0,0 +1,56 @@ +""" +Create Compliance Job - X API v2 +================================ +Endpoint: POST https://api.x.com/2/compliance/jobs +Docs: https://developer.x.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/post-compliance-jobs + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + return "https://api.x.com/2/compliance/jobs" + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ComplianceJobPython" + return r + + +def connect_to_endpoint(url, payload): + response = requests.post(url, auth=bearer_oauth, json=payload) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + + # Type can be "tweets" or "users" + payload = { + "type": "tweets", + "name": "my_compliance_job" + } + + json_response = connect_to_endpoint(url, payload) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + # Note the job id and upload_url from the response + # You'll need these to upload your dataset and download results + + +if __name__ == "__main__": + main() diff --git a/python/compliance/get_jobs.py b/python/compliance/get_jobs.py new file mode 100644 index 0000000..de65383 --- /dev/null +++ b/python/compliance/get_jobs.py @@ -0,0 +1,52 @@ +""" +Get Compliance Jobs - X API v2 +============================== +Endpoint: GET https://api.x.com/2/compliance/jobs +Docs: https://developer.x.com/en/docs/twitter-api/compliance/batch-compliance/api-reference/get-compliance-jobs + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + return "https://api.x.com/2/compliance/jobs" + + +def get_params(): + # Type can be "tweets" or "users" + return {"type": "tweets"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ComplianceJobsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.get(url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Manage-Lists/Manage-Followed-Lists/follow_list.py b/python/direct_messages/lookup.py similarity index 67% rename from Manage-Lists/Manage-Followed-Lists/follow_list.py rename to python/direct_messages/lookup.py index 827ae8c..3ba8f24 100644 --- a/Manage-Lists/Manage-Followed-Lists/follow_list.py +++ b/python/direct_messages/lookup.py @@ -1,24 +1,27 @@ +""" +Direct Messages Lookup - X API v2 +================================= +Endpoint: GET https://api.x.com/2/dm_events +Docs: https://developer.x.com/en/docs/twitter-api/direct-messages/lookup/api-reference/get-dm-events + +Authentication: OAuth 1.0a or OAuth 2.0 (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-follow with the list id you wish to follow. -payload = {"list_id": "list-id-to-follow"} +# DM event fields are adjustable. Options include: +# id, text, event_type, created_at, dm_conversation_id, +# sender_id, participant_ids, referenced_tweets, attachments +params = {"dm_event.fields": "id,text,event_type,created_at,sender_id"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -33,13 +36,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -61,9 +64,7 @@ ) # Making the request -response = oauth.post( - "https://api.twitter.com/2/users/{}/followed_lists".format(id), json=payload -) +response = oauth.get("https://api.x.com/2/dm_events", params=params) if response.status_code != 200: raise Exception( diff --git a/python/direct_messages/send.py b/python/direct_messages/send.py new file mode 100644 index 0000000..9299385 --- /dev/null +++ b/python/direct_messages/send.py @@ -0,0 +1,82 @@ +""" +Send Direct Message - X API v2 +============================== +Endpoint: POST https://api.x.com/2/dm_conversations/with/:participant_id/messages +Docs: https://developer.x.com/en/docs/twitter-api/direct-messages/manage/api-reference/post-dm-conversations-with-participant_id-messages + +Authentication: OAuth 1.0a or OAuth 2.0 (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + +from requests_oauthlib import OAuth1Session +import os +import json + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Replace with the user ID you want to send a DM to +participant_id = "recipient-user-id" + +# Message content +payload = {"text": "Hello! This is a test message."} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/dm_conversations/with/{}/messages".format(participant_id), + json=payload +) + +if response.status_code != 201: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/create.py b/python/lists/create.py new file mode 100644 index 0000000..cd51ff4 --- /dev/null +++ b/python/lists/create.py @@ -0,0 +1,80 @@ +""" +Create List - X API v2 +====================== +Endpoint: POST https://api.x.com/2/lists +Docs: https://developer.x.com/en/docs/twitter-api/lists/manage-lists/api-reference/post-lists + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + +from requests_oauthlib import OAuth1Session +import os +import json + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# List parameters +payload = { + "name": "My new list", + "description": "A description for my list", + "private": False +} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post("https://api.x.com/2/lists", json=payload) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Lists/delete_a_list.py b/python/lists/delete.py similarity index 73% rename from Manage-Lists/delete_a_list.py rename to python/lists/delete.py index 9edaa89..6d0b4ec 100644 --- a/Manage-Lists/delete_a_list.py +++ b/python/lists/delete.py @@ -1,22 +1,25 @@ +""" +Delete List - X API v2 +====================== +Endpoint: DELETE https://api.x.com/2/lists/:id +Docs: https://developer.x.com/en/docs/twitter-api/lists/manage-lists/api-reference/delete-lists-id + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-list-id with the id of the list you wish to delete. The authenticated user must own the list in order to delete - -id = "your-list-id" - +# Replace with the list ID you want to delete +list_id = "list-id-to-delete" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -31,13 +34,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -59,9 +62,7 @@ ) # Making the request -response = oauth.delete( - "https://api.twitter.com/2/lists/{}".format(id) -) +response = oauth.delete("https://api.x.com/2/lists/{}".format(list_id)) if response.status_code != 200: raise Exception( diff --git a/python/lists/lookup.py b/python/lists/lookup.py new file mode 100644 index 0000000..b736289 --- /dev/null +++ b/python/lists/lookup.py @@ -0,0 +1,55 @@ +""" +List Lookup - X API v2 +====================== +Endpoint: GET https://api.x.com/2/lists/:id +Docs: https://developer.x.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with the list ID you want to look up + list_id = "84839422" + return "https://api.x.com/2/lists/{}".format(list_id) + + +def get_params(): + # List fields are adjustable. Options include: + # created_at, follower_count, member_count, private, description, owner_id + return {"list.fields": "created_at,follower_count,member_count,owner_id,description"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListLookupPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Manage-Lists/update_a_list.py b/python/media/upload.py similarity index 57% rename from Manage-Lists/update_a_list.py rename to python/media/upload.py index fe27f87..130fa5b 100644 --- a/Manage-Lists/update_a_list.py +++ b/python/media/upload.py @@ -1,28 +1,28 @@ +""" +Media Upload - X API v2 +======================= +Endpoint: POST https://api.x.com/2/media/upload +Docs: https://developer.x.com/en/docs/twitter-api/media/upload-media/api-reference + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET + +This example demonstrates uploading an image to attach to a post. +""" + from requests_oauthlib import OAuth1Session import os import json - -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' +import base64 consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") -# Be sure to add replace update-name-of-list with the name you wish to call the list. -# name, description and private are all optional -payload = { "name": "update-name-of-list", - "description": "update-description-of-list", - "private": False} - - -# Be sure to replace your-list-id with the id of the list you wish to update. The authenticated user must own the list in order to update - -id = "your-list-id" - +# Path to the media file you want to upload +media_path = "path/to/your/image.jpg" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -37,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -64,10 +64,15 @@ resource_owner_secret=access_token_secret, ) -# Making the request -response = oauth.put( - "https://api.twitter.com/2/lists/{}".format(id), json=payload -) +# Read and encode the media file +with open(media_path, "rb") as media_file: + media_data = base64.b64encode(media_file.read()).decode("utf-8") + +# Upload the media (using v1.1 endpoint as v2 media upload is similar) +upload_url = "https://upload.twitter.com/1.1/media/upload.json" +payload = {"media_data": media_data} + +response = oauth.post(upload_url, data=payload) if response.status_code != 200: raise Exception( @@ -76,6 +81,11 @@ print("Response code: {}".format(response.status_code)) -# Saving the response as JSON +# Get the media_id to use when creating a post json_response = response.json() +media_id = json_response["media_id_string"] +print("Media ID: {}".format(media_id)) print(json.dumps(json_response, indent=4, sort_keys=True)) + +# You can now use this media_id when creating a post: +# payload = {"text": "My post with media!", "media": {"media_ids": [media_id]}} diff --git a/python/posts/counts_full_archive.py b/python/posts/counts_full_archive.py new file mode 100644 index 0000000..963c026 --- /dev/null +++ b/python/posts/counts_full_archive.py @@ -0,0 +1,52 @@ +""" +Full-Archive Post Counts - X API v2 +=================================== +Endpoint: GET https://api.x.com/2/tweets/counts/all +Docs: https://developer.x.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-all + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +Note: Requires Academic Research access. Returns counts from the entire archive. +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FullArchivePostCountsPython" + return r + + +def get_params(): + return { + "query": "from:XDevelopers", + "granularity": "day" + } + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = "https://api.x.com/2/tweets/counts/all" + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/counts_recent.py b/python/posts/counts_recent.py new file mode 100644 index 0000000..8f51666 --- /dev/null +++ b/python/posts/counts_recent.py @@ -0,0 +1,52 @@ +""" +Recent Post Counts - X API v2 +============================= +Endpoint: GET https://api.x.com/2/tweets/counts/recent +Docs: https://developer.x.com/en/docs/twitter-api/tweets/counts/api-reference/get-tweets-counts-recent + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +Note: Returns count of posts from the last 7 days matching your query. +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2PostCountsPython" + return r + + +def get_params(): + return { + "query": "from:XDevelopers", + "granularity": "day" + } + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = "https://api.x.com/2/tweets/counts/recent" + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Manage-Tweets/create_tweet.py b/python/posts/create_post.py similarity index 72% rename from Manage-Tweets/create_tweet.py rename to python/posts/create_post.py index a8efc85..63cf6fd 100644 --- a/Manage-Tweets/create_tweet.py +++ b/python/posts/create_post.py @@ -1,19 +1,26 @@ +""" +Create Post - X API v2 +====================== +Endpoint: POST https://api.x.com/2/tweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") -# Be sure to add replace the text of the with the text you wish to Tweet. You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. +# The text content of the post. You can also add parameters for polls, +# quote posts, reply settings, and more. payload = {"text": "Hello world!"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write" +request_token_url = "https://api.x.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -28,13 +35,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -57,7 +64,7 @@ # Making the request response = oauth.post( - "https://api.twitter.com/2/tweets", + "https://api.x.com/2/tweets", json=payload, ) diff --git a/Manage-Tweets/delete_tweet.py b/python/posts/delete_post.py similarity index 71% rename from Manage-Tweets/delete_tweet.py rename to python/posts/delete_post.py index 5aff4bc..0199ab0 100644 --- a/Manage-Tweets/delete_tweet.py +++ b/python/posts/delete_post.py @@ -1,22 +1,26 @@ +""" +Delete Post - X API v2 +====================== +Endpoint: DELETE https://api.x.com/2/tweets/:id +Docs: https://developer.x.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace tweet-id-to-delete with the id of the Tweet you wish to delete. The authenticated user must own the list in order to delete - -id = "tweet-id-to-delete" - +# Replace with the ID of the post you wish to delete. +# The authenticated user must own the post. +post_id = "post-id-to-delete" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -31,13 +35,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -59,7 +63,7 @@ ) # Making the request -response = oauth.delete("https://api.twitter.com/2/tweets/{}".format(id)) +response = oauth.delete("https://api.x.com/2/tweets/{}".format(post_id)) if response.status_code != 200: raise Exception( diff --git a/Manage-Lists/Manage-List-Members/add_member.py b/python/posts/like.py similarity index 71% rename from Manage-Lists/Manage-List-Members/add_member.py rename to python/posts/like.py index 4f542ab..5bcb4d6 100644 --- a/Manage-Lists/Manage-List-Members/add_member.py +++ b/python/posts/like.py @@ -1,24 +1,28 @@ +""" +Like a Post - X API v2 +====================== +Endpoint: POST https://api.x.com/2/users/:id/likes +Docs: https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/post-users-id-likes + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to replace your-list-id with your own list ID or one of an authenticating user - -id = "your-list-id" - -# Be sure to replace user-id-to-add with the user id you wish to add. -payload = {"user_id": "user-id-to-add"} +# Replace with the post ID you want to like +payload = {"tweet_id": "1354143047324299264"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -33,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -62,7 +66,7 @@ # Making the request response = oauth.post( - "https://api.twitter.com/2/lists/{}/members".format(id), json=payload + "https://api.x.com/2/users/{}/likes".format(user_id), json=payload ) if response.status_code != 200: diff --git a/python/posts/liked_posts.py b/python/posts/liked_posts.py new file mode 100644 index 0000000..cfafbf5 --- /dev/null +++ b/python/posts/liked_posts.py @@ -0,0 +1,53 @@ +""" +Posts Liked by User - X API v2 +============================== +Endpoint: GET https://api.x.com/2/users/:id/liked_tweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/get-users-id-liked_tweets + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with the user ID you want to get liked posts for + user_id = "2244994945" + return "https://api.x.com/2/users/{}/liked_tweets".format(user_id) + + +def get_params(): + return {"tweet.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2LikedPostsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/liking_users.py b/python/posts/liking_users.py new file mode 100644 index 0000000..9e7350d --- /dev/null +++ b/python/posts/liking_users.py @@ -0,0 +1,53 @@ +""" +Users Who Liked a Post - X API v2 +================================= +Endpoint: GET https://api.x.com/2/tweets/:id/liking_users +Docs: https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with the post ID you want to get liking users for + post_id = "1354143047324299264" + return "https://api.x.com/2/tweets/{}/liking_users".format(post_id) + + +def get_params(): + return {"user.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2LikingUsersPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/lookup.py b/python/posts/lookup.py new file mode 100644 index 0000000..802a466 --- /dev/null +++ b/python/posts/lookup.py @@ -0,0 +1,61 @@ +""" +Post Lookup - X API v2 +====================== +Endpoint: GET https://api.x.com/2/tweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Post IDs to look up (comma-separated, up to 100) + post_ids = "ids=1278747501642657792,1255542774432063488" + + # Post fields are adjustable. Options include: + # attachments, author_id, context_annotations, conversation_id, + # created_at, entities, geo, id, in_reply_to_user_id, lang, + # non_public_metrics, organic_metrics, possibly_sensitive, + # promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + post_fields = "tweet.fields=created_at,author_id,lang,source,public_metrics,context_annotations,entities" + url = "https://api.x.com/2/tweets?{}&{}".format(post_ids, post_fields) + return url + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2PostLookupPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/quote_posts.py b/python/posts/quote_posts.py new file mode 100644 index 0000000..038ebea --- /dev/null +++ b/python/posts/quote_posts.py @@ -0,0 +1,54 @@ +""" +Quote Posts Lookup - X API v2 +============================= +Endpoint: GET https://api.x.com/2/tweets/:id/quote_tweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + +# Replace with the post ID you want to get quotes for +post_id = "1409931481552543749" + + +def get_params(): + return {"tweet.fields": "created_at"} + + +def create_url(): + return "https://api.x.com/2/tweets/{}/quote_tweets".format(post_id) + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2QuotePostsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Manage-Blocks/block_a_user.py b/python/posts/repost.py similarity index 69% rename from Manage-Blocks/block_a_user.py rename to python/posts/repost.py index 92e1fdb..e5cd46e 100644 --- a/Manage-Blocks/block_a_user.py +++ b/python/posts/repost.py @@ -1,24 +1,28 @@ +""" +Repost (Retweet) - X API v2 +=========================== +Endpoint: POST https://api.x.com/2/users/:id/retweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/post-users-id-retweets + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID (find using user lookup endpoint) +user_id = "your-user-id" -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace id-to-block with the user id you wish to block. -payload = {"target_user_id": "id-to-block"} +# Replace with the post ID you want to repost +payload = {"tweet_id": "1412865600439738368"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -33,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -62,7 +66,7 @@ # Making the request response = oauth.post( - "https://api.twitter.com/2/users/{}/blocking".format(id), json=payload + "https://api.x.com/2/users/{}/retweets".format(user_id), json=payload ) if response.status_code != 200: diff --git a/python/posts/reposted_by.py b/python/posts/reposted_by.py new file mode 100644 index 0000000..c2ff4fc --- /dev/null +++ b/python/posts/reposted_by.py @@ -0,0 +1,53 @@ +""" +Reposted By (Users who retweeted) - X API v2 +============================================ +Endpoint: GET https://api.x.com/2/tweets/:id/retweeted_by +Docs: https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/get-tweets-id-retweeted_by + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with the post ID you want to get reposters for + post_id = "1354143047324299264" + return "https://api.x.com/2/tweets/{}/retweeted_by".format(post_id) + + +def get_params(): + return {"user.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2RepostedByPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/search_full_archive.py b/python/posts/search_full_archive.py new file mode 100644 index 0000000..e9c9bc8 --- /dev/null +++ b/python/posts/search_full_archive.py @@ -0,0 +1,53 @@ +""" +Full-Archive Search - X API v2 +============================== +Endpoint: GET https://api.x.com/2/tweets/search/all +Docs: https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +Note: Requires Academic Research access. Returns posts from the entire archive. +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/tweets/search/all" + +# Optional params: start_time, end_time, since_id, until_id, max_results, +# next_token, expansions, tweet.fields, media.fields, poll.fields, +# place.fields, user.fields +query_params = { + 'query': '(from:XDevelopers -is:retweet) OR #xapi', + 'tweet.fields': 'author_id' +} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FullArchiveSearchPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.get(url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(search_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Recent-Search/recent_search.py b/python/posts/search_recent.py similarity index 54% rename from Recent-Search/recent_search.py rename to python/posts/search_recent.py index cb97511..9538a83 100644 --- a/Recent-Search/recent_search.py +++ b/python/posts/search_recent.py @@ -1,27 +1,40 @@ +""" +Recent Search - X API v2 +======================== +Endpoint: GET https://api.x.com/2/tweets/search/recent +Docs: https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN + +Note: Returns posts from the last 7 days. +""" + import requests import os import json -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") -search_url = "https://api.twitter.com/2/tweets/search/recent" +search_url = "https://api.x.com/2/tweets/search/recent" -# Optional params: start_time,end_time,since_id,until_id,max_results,next_token, -# expansions,tweet.fields,media.fields,poll.fields,place.fields,user.fields -query_params = {'query': '(from:twitterdev -is:retweet) OR #twitterdev','tweet.fields': 'author_id'} +# Optional params: start_time, end_time, since_id, until_id, max_results, next_token, +# expansions, tweet.fields, media.fields, poll.fields, place.fields, user.fields +query_params = { + 'query': '(from:XDevelopers -is:retweet) OR #xapi', + 'tweet.fields': 'author_id' +} def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2RecentSearchPython" return r + def connect_to_endpoint(url, params): response = requests.get(url, auth=bearer_oauth, params=params) print(response.status_code) diff --git a/Manage-Lists/Manage-Followed-Lists/unfollow_list.py b/python/posts/undo_repost.py similarity index 69% rename from Manage-Lists/Manage-Followed-Lists/unfollow_list.py rename to python/posts/undo_repost.py index ac5f779..fb87599 100644 --- a/Manage-Lists/Manage-Followed-Lists/unfollow_list.py +++ b/python/posts/undo_repost.py @@ -1,25 +1,28 @@ +""" +Undo Repost (Unretweet) - X API v2 +================================== +Endpoint: DELETE https://api.x.com/2/users/:id/retweets/:source_tweet_id +Docs: https://developer.x.com/en/docs/twitter-api/tweets/retweets/api-reference/delete-users-id-retweets-tweet_id + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-unfollow with the id of the user you wish to unfollow. -list_id = "list-id-to-unfollow" - +# Replace with the post ID you want to undo repost for +source_post_id = "post-id-to-unrepost" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -34,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -63,7 +66,7 @@ # Making the request response = oauth.delete( - "https://api.twitter.com/2/users/{}/followed_lists/{}".format(id, list_id) + "https://api.x.com/2/users/{}/retweets/{}".format(user_id, source_post_id) ) if response.status_code != 200: diff --git a/Manage-Lists/Manage-List-Members/remove_member.py b/python/posts/unlike.py similarity index 70% rename from Manage-Lists/Manage-List-Members/remove_member.py rename to python/posts/unlike.py index 01a1f8e..4691558 100644 --- a/Manage-Lists/Manage-List-Members/remove_member.py +++ b/python/posts/unlike.py @@ -1,25 +1,28 @@ +""" +Unlike a Post - X API v2 +======================== +Endpoint: DELETE https://api.x.com/2/users/:id/likes/:tweet_id +Docs: https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/delete-users-id-likes-tweet_id + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to replace your-list-id with your own list ID or one of an authenticated user -id = "your-list-id" - -# Be sure to add replace user-id-to-remove with the id of the user you wish to remove. -# You can find a user ID by using the user lookup endpoint -user_id = "user-id-to-remove" - +# Replace with the post ID you want to unlike +post_id = "post-id-to-unlike" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -34,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -63,7 +66,7 @@ # Making the request response = oauth.delete( - "https://api.twitter.com/2/lists/{}/members/{}".format(id, user_id) + "https://api.x.com/2/users/{}/likes/{}".format(user_id, post_id) ) if response.status_code != 200: diff --git a/python/requirements.txt b/python/requirements.txt new file mode 100644 index 0000000..f4803a5 --- /dev/null +++ b/python/requirements.txt @@ -0,0 +1,10 @@ +# X API v2 Python Examples - Dependencies + +# HTTP client +requests>=2.28.0 + +# OAuth 1.0a authentication +requests-oauthlib>=1.3.0 + +# OAuth 2.0 with PKCE (for bookmarks and other OAuth 2.0 endpoints) +# oauthlib>=3.2.0 diff --git a/python/spaces/lookup.py b/python/spaces/lookup.py new file mode 100644 index 0000000..5a0f185 --- /dev/null +++ b/python/spaces/lookup.py @@ -0,0 +1,55 @@ +""" +Spaces Lookup - X API v2 +======================== +Endpoint: GET https://api.x.com/2/spaces +Docs: https://developer.x.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Space IDs to look up (comma-separated) + space_ids = "ids=1DXxyRYNejbKM" + + # Space fields are adjustable. Options include: + # host_ids, created_at, creator_id, id, lang, invited_user_ids, + # participant_count, speaker_ids, started_at, ended_at, subscriber_count, + # topic_ids, state, title, updated_at, scheduled_start, is_ticketed + space_fields = "space.fields=host_ids,created_at,creator_id,participant_count,title,state" + url = "https://api.x.com/2/spaces?{}&{}".format(space_ids, space_fields) + return url + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2SpacesLookupPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/spaces/search.py b/python/spaces/search.py new file mode 100644 index 0000000..7678e2e --- /dev/null +++ b/python/spaces/search.py @@ -0,0 +1,55 @@ +""" +Spaces Search - X API v2 +======================== +Endpoint: GET https://api.x.com/2/spaces/search +Docs: https://developer.x.com/en/docs/twitter-api/spaces/search/api-reference/get-spaces-search + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + query = "query=crypto" + state = "state=live" + + # Space fields are adjustable. Options include: + # host_ids, created_at, creator_id, id, lang, invited_user_ids, + # participant_count, speaker_ids, started_at, ended_at, subscriber_count, + # topic_ids, state, title, updated_at, scheduled_start, is_ticketed + space_fields = "space.fields=host_ids,created_at,participant_count,title" + url = "https://api.x.com/2/spaces/search?{}&{}&{}".format(query, state, space_fields) + return url + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2SpacesSearchPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Filtered-Stream/filtered_stream.py b/python/streams/filtered_stream.py similarity index 75% rename from Filtered-Stream/filtered_stream.py rename to python/streams/filtered_stream.py index 346ca32..cdb937e 100644 --- a/Filtered-Stream/filtered_stream.py +++ b/python/streams/filtered_stream.py @@ -1,9 +1,23 @@ +""" +Filtered Stream - X API v2 +========================== +Endpoint: GET https://api.x.com/2/tweets/search/stream +Docs: https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +This example demonstrates: +1. Getting existing rules +2. Deleting all existing rules +3. Setting new rules +4. Connecting to the stream +""" + import requests import os import json -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") @@ -11,7 +25,6 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2FilteredStreamPython" return r @@ -19,7 +32,7 @@ def bearer_oauth(r): def get_rules(): response = requests.get( - "https://api.twitter.com/2/tweets/search/stream/rules", auth=bearer_oauth + "https://api.x.com/2/tweets/search/stream/rules", auth=bearer_oauth ) if response.status_code != 200: raise Exception( @@ -36,7 +49,7 @@ def delete_all_rules(rules): ids = list(map(lambda rule: rule["id"], rules["data"])) payload = {"delete": {"ids": ids}} response = requests.post( - "https://api.twitter.com/2/tweets/search/stream/rules", + "https://api.x.com/2/tweets/search/stream/rules", auth=bearer_oauth, json=payload ) @@ -50,14 +63,14 @@ def delete_all_rules(rules): def set_rules(delete): - # You can adjust the rules if needed + # Adjust rules as needed sample_rules = [ {"value": "dog has:images", "tag": "dog pictures"}, {"value": "cat has:images -grumpy", "tag": "cat pictures"}, ] payload = {"add": sample_rules} response = requests.post( - "https://api.twitter.com/2/tweets/search/stream/rules", + "https://api.x.com/2/tweets/search/stream/rules", auth=bearer_oauth, json=payload, ) @@ -70,7 +83,7 @@ def set_rules(delete): def get_stream(set): response = requests.get( - "https://api.twitter.com/2/tweets/search/stream", auth=bearer_oauth, stream=True, + "https://api.x.com/2/tweets/search/stream", auth=bearer_oauth, stream=True, ) print(response.status_code) if response.status_code != 200: diff --git a/Sampled-Stream/sampled-stream.py b/python/streams/sampled_stream.py similarity index 55% rename from Sampled-Stream/sampled-stream.py rename to python/streams/sampled_stream.py index 4b28641..456b31b 100644 --- a/Sampled-Stream/sampled-stream.py +++ b/python/streams/sampled_stream.py @@ -1,47 +1,50 @@ +""" +Sampled Stream (1% Volume) - X API v2 +===================================== +Endpoint: GET https://api.x.com/2/tweets/sample/stream +Docs: https://developer.x.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +Note: Returns approximately 1% of all public posts in real-time. +""" + import requests import os import json -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") -def create_url(): - return "https://api.twitter.com/2/tweets/sample/stream" - - def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2SampledStreamPython" return r -def connect_to_endpoint(url): - response = requests.request("GET", url, auth=bearer_oauth, stream=True) +def get_stream(): + response = requests.get( + "https://api.x.com/2/tweets/sample/stream", auth=bearer_oauth, stream=True, + ) print(response.status_code) - for response_line in response.iter_lines(): - if response_line: - json_response = json.loads(response_line) - print(json.dumps(json_response, indent=4, sort_keys=True)) if response.status_code != 200: raise Exception( - "Request returned an error: {} {}".format( + "Cannot get stream (HTTP {}): {}".format( response.status_code, response.text ) ) + for response_line in response.iter_lines(): + if response_line: + json_response = json.loads(response_line) + print(json.dumps(json_response, indent=4, sort_keys=True)) def main(): - url = create_url() - timeout = 0 - while True: - connect_to_endpoint(url) - timeout += 1 + get_stream() if __name__ == "__main__": diff --git a/List-lookup/Pinned-Lists-lookup/Pinned-List.py b/python/timelines/home_timeline.py similarity index 63% rename from List-lookup/Pinned-Lists-lookup/Pinned-List.py rename to python/timelines/home_timeline.py index a27fd4c..f8a8d23 100644 --- a/List-lookup/Pinned-Lists-lookup/Pinned-List.py +++ b/python/timelines/home_timeline.py @@ -1,26 +1,28 @@ +""" +Reverse Chronological Home Timeline - X API v2 +============================================== +Endpoint: GET https://api.x.com/2/users/:id/reverse_chronological_timeline +Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-reverse-chronological-timeline + +Authentication: OAuth 1.0a or OAuth 2.0 (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") - -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# List fields are adjustable, options include: -# created_at, description, owner_id, -# private, follower_count, member_count, -list_fields = "list.fields=created_at,description,private" +# Post fields are adjustable. Options include: +# attachments, author_id, context_annotations, conversation_id, +# created_at, entities, geo, id, in_reply_to_user_id, lang, +# possibly_sensitive, public_metrics, referenced_tweets, source, text +params = {"tweet.fields": "created_at"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -35,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -53,6 +55,7 @@ access_token = oauth_tokens["oauth_token"] access_token_secret = oauth_tokens["oauth_token_secret"] +user_id = oauth_tokens["user_id"] # Make the request oauth = OAuth1Session( @@ -64,7 +67,9 @@ # Making the request response = oauth.get( - "https://api.twitter.com/2/users/{}/pinned_lists".format(id), params=list_fields) + "https://api.x.com/2/users/{}/reverse_chronological_timeline".format(user_id), + params=params +) if response.status_code != 200: raise Exception( diff --git a/User-Mention-Timeline/user_mentions.py b/python/timelines/user_mentions.py similarity index 51% rename from User-Mention-Timeline/user_mentions.py rename to python/timelines/user_mentions.py index fbf94c1..2993206 100644 --- a/User-Mention-Timeline/user_mentions.py +++ b/python/timelines/user_mentions.py @@ -1,26 +1,27 @@ +""" +User Mentions Timeline - X API v2 +================================= +Endpoint: GET https://api.x.com/2/users/:id/mentions +Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + import requests import os import json -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Replace with user ID below - user_id = 2244994945 - return "https://api.twitter.com/2/users/{}/mentions".format(user_id) + # Replace with the user ID you want to get mentions for + user_id = "2244994945" + return "https://api.x.com/2/users/{}/mentions".format(user_id) def get_params(): - # Tweet fields are adjustable. - # Options include: - # attachments, author_id, context_annotations, - # conversation_id, created_at, entities, geo, id, - # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, - # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, - # source, text, and withheld return {"tweet.fields": "created_at"} @@ -28,7 +29,6 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2UserMentionsPython" return r @@ -38,11 +38,7 @@ def connect_to_endpoint(url, params): response = requests.request("GET", url, auth=bearer_oauth, params=params) print(response.status_code) if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) + raise Exception(response.status_code, response.text) return response.json() @@ -55,4 +51,3 @@ def main(): if __name__ == "__main__": main() - \ No newline at end of file diff --git a/python/timelines/user_posts.py b/python/timelines/user_posts.py new file mode 100644 index 0000000..a691277 --- /dev/null +++ b/python/timelines/user_posts.py @@ -0,0 +1,57 @@ +""" +User Posts Timeline - X API v2 +============================== +Endpoint: GET https://api.x.com/2/users/:id/tweets +Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with the user ID you want to get posts for + user_id = "2244994945" + return "https://api.x.com/2/users/{}/tweets".format(user_id) + + +def get_params(): + # Post fields are adjustable. Options include: + # attachments, author_id, context_annotations, conversation_id, + # created_at, entities, geo, id, in_reply_to_user_id, lang, + # possibly_sensitive, public_metrics, referenced_tweets, source, text + return {"tweet.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2UserPostsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/usage/get_usage.py b/python/usage/get_usage.py new file mode 100644 index 0000000..7042699 --- /dev/null +++ b/python/usage/get_usage.py @@ -0,0 +1,53 @@ +""" +Usage Posts - X API v2 +====================== +Endpoint: GET https://api.x.com/2/usage/tweets +Docs: https://developer.x.com/en/docs/twitter-api/usage/api-reference/get-usage-tweets + +Authentication: Bearer Token (App-only) +Required env vars: BEARER_TOKEN + +Returns the number of posts read from the API. +""" + +import requests +import os +import json + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + return "https://api.x.com/2/usage/tweets" + + +def get_params(): + return {"days": 7} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2UsagePython" + return r + + +def connect_to_endpoint(url, params): + response = requests.get(url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/Manage-Mutes/mute_a_user.py b/python/users/block.py similarity index 70% rename from Manage-Mutes/mute_a_user.py rename to python/users/block.py index de9fec6..77da5db 100644 --- a/Manage-Mutes/mute_a_user.py +++ b/python/users/block.py @@ -1,24 +1,28 @@ +""" +Block User - X API v2 +===================== +Endpoint: POST https://api.x.com/2/users/:id/blocking +Docs: https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/post-users-user_id-blocking + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to replace id-to-mute with the user id you wish to mute. -payload = {"target_user_id": "id-to-mute"} +# Replace with the user ID you want to block +payload = {"target_user_id": "target-user-id"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -33,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -62,7 +66,7 @@ # Making the request response = oauth.post( - "https://api.twitter.com/2/users/{}/muting".format(id), json=payload + "https://api.x.com/2/users/{}/blocking".format(user_id), json=payload ) if response.status_code != 200: diff --git a/Blocks-Lookup/lookup_blocks.py b/python/users/blocked.py similarity index 66% rename from Blocks-Lookup/lookup_blocks.py rename to python/users/blocked.py index 84a2ba3..7bb4a0c 100644 --- a/Blocks-Lookup/lookup_blocks.py +++ b/python/users/blocked.py @@ -1,25 +1,29 @@ +""" +Blocked Users Lookup - X API v2 +=============================== +Endpoint: GET https://api.x.com/2/users/:id/blocking +Docs: https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# To set your enviornment variables in your terminal run the following line: -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") -# Be sure to replace your-user-id with your own user ID or one of an authenticating user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -params = {"user.fields": "created_at,description"} -# User fields are adjustable, options include: +# User fields are adjustable. Options include: # created_at, description, entities, id, location, name, # pinned_tweet_id, profile_image_url, protected, # public_metrics, url, username, verified, and withheld +fields = "user.fields=created_at,description" +params = {"user.fields": fields} -request_token_url = "https://api.twitter.com/oauth/request_token" +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -34,13 +38,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -50,7 +54,6 @@ ) oauth_tokens = oauth.fetch_access_token(access_token_url) - access_token = oauth_tokens["oauth_token"] access_token_secret = oauth_tokens["oauth_token_secret"] @@ -62,16 +65,20 @@ resource_owner_secret=access_token_secret, ) +user_id = oauth_tokens["user_id"] + +# Making the request response = oauth.get( - "https://api.twitter.com/2/users/{}/blocking".format(id), params=params + "https://api.x.com/2/users/{}/blocking".format(user_id), params=params ) if response.status_code != 200: raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text) + "Request returned an error: {} {}".format(response.status_code, response.text) ) print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON json_response = response.json() print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Follows-Lookup/followers_lookup.py b/python/users/followers.py similarity index 60% rename from Follows-Lookup/followers_lookup.py rename to python/users/followers.py index 314baad..35f87de 100644 --- a/Follows-Lookup/followers_lookup.py +++ b/python/users/followers.py @@ -1,16 +1,24 @@ +""" +User Followers Lookup - X API v2 +================================ +Endpoint: GET https://api.x.com/2/users/:id/followers +Docs: https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + import requests import os import json -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Replace with user ID below - user_id = 2244994945 - return "https://api.twitter.com/2/users/{}/followers".format(user_id) + # Replace with the user ID you want to get followers for + user_id = "2244994945" + return "https://api.x.com/2/users/{}/followers".format(user_id) def get_params(): @@ -21,7 +29,6 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2FollowersLookupPython" return r @@ -31,11 +38,7 @@ def connect_to_endpoint(url, params): response = requests.request("GET", url, auth=bearer_oauth, params=params) print(response.status_code) if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) + raise Exception(response.status_code, response.text) return response.json() diff --git a/Follows-Lookup/following_lookup.py b/python/users/following.py similarity index 60% rename from Follows-Lookup/following_lookup.py rename to python/users/following.py index 1dd0c21..dba3fb3 100644 --- a/Follows-Lookup/following_lookup.py +++ b/python/users/following.py @@ -1,16 +1,24 @@ +""" +User Following Lookup - X API v2 +================================ +Endpoint: GET https://api.x.com/2/users/:id/following +Docs: https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-following + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + import requests import os import json -# To set your environment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Replace with user ID below - user_id = 2244994945 - return "https://api.twitter.com/2/users/{}/following".format(user_id) + # Replace with the user ID you want to get following for + user_id = "2244994945" + return "https://api.x.com/2/users/{}/following".format(user_id) def get_params(): @@ -21,7 +29,6 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2FollowingLookupPython" return r @@ -31,11 +38,7 @@ def connect_to_endpoint(url, params): response = requests.request("GET", url, auth=bearer_oauth, params=params) print(response.status_code) if response.status_code != 200: - raise Exception( - "Request returned an error: {} {}".format( - response.status_code, response.text - ) - ) + raise Exception(response.status_code, response.text) return response.json() diff --git a/User-Lookup/get_users_with_bearer_token.py b/python/users/lookup.py similarity index 63% rename from User-Lookup/get_users_with_bearer_token.py rename to python/users/lookup.py index c751f58..fb984e6 100644 --- a/User-Lookup/get_users_with_bearer_token.py +++ b/python/users/lookup.py @@ -1,22 +1,30 @@ +""" +User Lookup - X API v2 +====================== +Endpoint: GET https://api.x.com/2/users/by +Docs: https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by + +Authentication: Bearer Token (App-only) or OAuth (User Context) +Required env vars: BEARER_TOKEN +""" + import requests import os import json -# To set your enviornment variables in your terminal run the following line: -# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Specify the usernames that you want to lookup below - # You can enter up to 100 comma-separated values. - usernames = "usernames=TwitterDev,TwitterAPI" - user_fields = "user.fields=description,created_at" - # User fields are adjustable, options include: + # Specify the usernames to lookup (up to 100 comma-separated) + usernames = "usernames=XDevelopers,X" + + # User fields are adjustable. Options include: # created_at, description, entities, id, location, name, # pinned_tweet_id, profile_image_url, protected, # public_metrics, url, username, verified, and withheld - url = "https://api.twitter.com/2/users/by?{}&{}".format(usernames, user_fields) + user_fields = "user.fields=description,created_at" + url = "https://api.x.com/2/users/by?{}&{}".format(usernames, user_fields) return url @@ -24,14 +32,13 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ - r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2UserLookupPython" return r def connect_to_endpoint(url): - response = requests.request("GET", url, auth=bearer_oauth,) + response = requests.request("GET", url, auth=bearer_oauth) print(response.status_code) if response.status_code != 200: raise Exception( diff --git a/User-Lookup/get_users_me_user_context.py b/python/users/me.py similarity index 71% rename from User-Lookup/get_users_me_user_context.py rename to python/users/me.py index f4a3bd4..819ea46 100644 --- a/User-Lookup/get_users_me_user_context.py +++ b/python/users/me.py @@ -1,23 +1,29 @@ +""" +Authenticated User Lookup (Me) - X API v2 +========================================= +Endpoint: GET https://api.x.com/2/users/me +Docs: https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-me + +Authentication: OAuth 1.0a or OAuth 2.0 (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") -# User fields are adjustable, options include: +# User fields are adjustable. Options include: # created_at, description, entities, id, location, name, # pinned_tweet_id, profile_image_url, protected, # public_metrics, url, username, verified, and withheld -fields = "created_at,description" +fields = "user.fields=description,created_at" params = {"user.fields": fields} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -31,14 +37,14 @@ resource_owner_secret = fetch_response.get("oauth_token_secret") print("Got OAuth token: %s" % resource_owner_key) -# # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -59,7 +65,8 @@ resource_owner_secret=access_token_secret, ) -response = oauth.get("https://api.twitter.com/2/users/me", params=params) +# Making the request +response = oauth.get("https://api.x.com/2/users/me", params=params) if response.status_code != 200: raise Exception( @@ -68,6 +75,6 @@ print("Response code: {}".format(response.status_code)) +# Saving the response as JSON json_response = response.json() - print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Lists/create_a_list.py b/python/users/mute.py similarity index 70% rename from Manage-Lists/create_a_list.py rename to python/users/mute.py index a4ece50..ce37e70 100644 --- a/Manage-Lists/create_a_list.py +++ b/python/users/mute.py @@ -1,23 +1,28 @@ +""" +Mute User - X API v2 +==================== +Endpoint: POST https://api.x.com/2/users/:id/muting +Docs: https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/post-users-user_id-muting + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to add replace name-of-list with the name you wish to call the list. -# description and private keys are optional -payload = { "name": "name-of-list", - "description": "description-of-list", - "private": False} +# Replace with the user ID you want to mute +payload = {"target_user_id": "target-user-id"} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -32,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -61,10 +66,10 @@ # Making the request response = oauth.post( - "https://api.twitter.com/2/lists", json=payload + "https://api.x.com/2/users/{}/muting".format(user_id), json=payload ) -if response.status_code != 201: +if response.status_code != 200: raise Exception( "Request returned an error: {} {}".format(response.status_code, response.text) ) diff --git a/User-Lookup/get_users_with_user_context.py b/python/users/muted.py similarity index 70% rename from User-Lookup/get_users_with_user_context.py rename to python/users/muted.py index c295d4b..01aaa29 100644 --- a/User-Lookup/get_users_with_user_context.py +++ b/python/users/muted.py @@ -1,23 +1,29 @@ +""" +Muted Users Lookup - X API v2 +============================= +Endpoint: GET https://api.x.com/2/users/:id/muting +Docs: https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") -# User fields are adjustable, options include: +# User fields are adjustable. Options include: # created_at, description, entities, id, location, name, # pinned_tweet_id, profile_image_url, protected, # public_metrics, url, username, verified, and withheld -fields = "created_at,description" -params = {"usernames": "TwitterDev,TwitterAPI", "user.fields": fields} +fields = "user.fields=created_at,description" +params = {"user.fields": fields} # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -31,14 +37,14 @@ resource_owner_secret = fetch_response.get("oauth_token_secret") print("Got OAuth token: %s" % resource_owner_key) -# # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -59,8 +65,11 @@ resource_owner_secret=access_token_secret, ) +user_id = oauth_tokens["user_id"] + +# Making the request response = oauth.get( - "https://api.twitter.com/2/users/by", params=params + "https://api.x.com/2/users/{}/muting".format(user_id), params=params ) if response.status_code != 200: @@ -70,6 +79,6 @@ print("Response code: {}".format(response.status_code)) +# Saving the response as JSON json_response = response.json() - print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/Manage-Lists/Manage-Pinned-Lists/unpin_list.py b/python/users/unblock.py similarity index 70% rename from Manage-Lists/Manage-Pinned-Lists/unpin_list.py rename to python/users/unblock.py index dab8620..be374b8 100644 --- a/Manage-Lists/Manage-Pinned-Lists/unpin_list.py +++ b/python/users/unblock.py @@ -1,25 +1,28 @@ +""" +Unblock User - X API v2 +======================= +Endpoint: DELETE https://api.x.com/2/users/:source_user_id/blocking/:target_user_id +Docs: https://developer.x.com/en/docs/twitter-api/users/blocks/api-reference/delete-users-user_id-blocking + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + from requests_oauthlib import OAuth1Session import os import json -# In your terminal please set your environment variables by running the following lines of code. -# export 'CONSUMER_KEY'='' -# export 'CONSUMER_SECRET'='' - consumer_key = os.environ.get("CONSUMER_KEY") consumer_secret = os.environ.get("CONSUMER_SECRET") +# Replace with your own user ID +user_id = "your-user-id" -# Be sure to replace your-user-id with your own user ID or one of an authenticated user -# You can find a user ID by using the user lookup endpoint -id = "your-user-id" - -# Be sure to add replace list-id-to-unpin with the id of the user you wish to unpin. -list_id = "list-id-to-unpin" - +# Replace with the user ID you want to unblock +target_user_id = "target-user-id" # Get request token -request_token_url = "https://api.twitter.com/oauth/request_token" +request_token_url = "https://api.x.com/oauth/request_token" oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) try: @@ -34,13 +37,13 @@ print("Got OAuth token: %s" % resource_owner_key) # Get authorization -base_authorization_url = "https://api.twitter.com/oauth/authorize" +base_authorization_url = "https://api.x.com/oauth/authorize" authorization_url = oauth.authorization_url(base_authorization_url) print("Please go here and authorize: %s" % authorization_url) verifier = input("Paste the PIN here: ") # Get the access token -access_token_url = "https://api.twitter.com/oauth/access_token" +access_token_url = "https://api.x.com/oauth/access_token" oauth = OAuth1Session( consumer_key, client_secret=consumer_secret, @@ -63,7 +66,7 @@ # Making the request response = oauth.delete( - "https://api.twitter.com/2/users/{}/pinned_lists/{}".format(id, list_id) + "https://api.x.com/2/users/{}/blocking/{}".format(user_id, target_user_id) ) if response.status_code != 200: diff --git a/python/users/unmute.py b/python/users/unmute.py new file mode 100644 index 0000000..b1d607f --- /dev/null +++ b/python/users/unmute.py @@ -0,0 +1,81 @@ +""" +Unmute User - X API v2 +====================== +Endpoint: DELETE https://api.x.com/2/users/:source_user_id/muting/:target_user_id +Docs: https://developer.x.com/en/docs/twitter-api/users/mutes/api-reference/delete-users-user_id-muting + +Authentication: OAuth 1.0a (User Context) +Required env vars: CONSUMER_KEY, CONSUMER_SECRET +""" + +from requests_oauthlib import OAuth1Session +import os +import json + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Replace with your own user ID +user_id = "your-user-id" + +# Replace with the user ID you want to unmute +target_user_id = "target-user-id" + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/muting/{}".format(user_id, target_user_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/ruby/Gemfile b/ruby/Gemfile new file mode 100644 index 0000000..5d49520 --- /dev/null +++ b/ruby/Gemfile @@ -0,0 +1,9 @@ +# X API v2 Ruby Examples - Dependencies + +source 'https://rubygems.org' + +# HTTP client +gem 'typhoeus', '~> 1.4' + +# OAuth 1.0a authentication +gem 'oauth', '~> 1.1' diff --git a/ruby/README.md b/ruby/README.md new file mode 100644 index 0000000..c8cb19c --- /dev/null +++ b/ruby/README.md @@ -0,0 +1,67 @@ +# X API v2 - Ruby Examples + +Working Ruby code samples for the X (formerly Twitter) API v2. + +## Setup + +### 1. Install Ruby 2.7+ + +```bash +ruby --version +``` + +### 2. Install dependencies + +```bash +gem install typhoeus +gem install oauth # For OAuth 1.0a examples +``` + +### 3. Set environment variables + +For **Bearer Token** authentication (app-only): +```bash +export BEARER_TOKEN='your_bearer_token' +``` + +For **OAuth 1.0a** authentication (user context): +```bash +export CONSUMER_KEY='your_consumer_key' +export CONSUMER_SECRET='your_consumer_secret' +``` + +## Examples by Category + +### Posts +| File | Description | Auth | +|------|-------------|------| +| `posts/search_recent.rb` | Search recent posts (7 days) | Bearer | +| `posts/lookup.rb` | Look up posts by ID | Bearer | + +### Users +| File | Description | Auth | +|------|-------------|------| +| `users/lookup.rb` | Look up users by username | Bearer | +| `users/followers.rb` | Get user's followers | Bearer | + +### Timelines +| File | Description | Auth | +|------|-------------|------| +| `timelines/user_posts.rb` | User's posts timeline | Bearer | + +### Lists +| File | Description | Auth | +|------|-------------|------| +| `lists/lookup.rb` | Look up a list | Bearer | + +## Running Examples + +```bash +# Make sure environment variables are set +ruby posts/search_recent.rb +``` + +## More Information + +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [X Developer Portal](https://developer.x.com/en/portal/dashboard) diff --git a/ruby/lists/lookup.rb b/ruby/lists/lookup.rb new file mode 100644 index 0000000..e8d4174 --- /dev/null +++ b/ruby/lists/lookup.rb @@ -0,0 +1,39 @@ +# List Lookup - X API v2 +# +# Endpoint: GET https://api.x.com/2/lists/:id +# Docs: https://developer.x.com/en/docs/twitter-api/lists/list-lookup/api-reference/get-lists-id +# +# Authentication: Bearer Token (App-only) or OAuth (User Context) +# Required env vars: BEARER_TOKEN + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +# Replace with the list ID you want to look up +list_id = "84839422" +url = "https://api.x.com/2/lists/#{list_id}" + +query_params = { + "list.fields": "created_at,follower_count,member_count,owner_id,description" +} + +def lookup_list(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lookup_list(url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/lookup.rb b/ruby/posts/lookup.rb new file mode 100644 index 0000000..293d5ea --- /dev/null +++ b/ruby/posts/lookup.rb @@ -0,0 +1,40 @@ +# Post Lookup - X API v2 +# +# Endpoint: GET https://api.x.com/2/tweets +# Docs: https://developer.x.com/en/docs/twitter-api/tweets/lookup/api-reference/get-tweets +# +# Authentication: Bearer Token (App-only) or OAuth (User Context) +# Required env vars: BEARER_TOKEN + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +# Post IDs to look up (comma-separated, up to 100) +post_ids = "1278747501642657792,1255542774432063488" +url = "https://api.x.com/2/tweets" + +query_params = { + "ids": post_ids, + "tweet.fields": "created_at,author_id,lang,source,public_metrics" +} + +def lookup_posts(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2PostLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lookup_posts(url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/search_recent.rb b/ruby/posts/search_recent.rb new file mode 100644 index 0000000..e5e99ec --- /dev/null +++ b/ruby/posts/search_recent.rb @@ -0,0 +1,47 @@ +# Recent Search - X API v2 +# +# Endpoint: GET https://api.x.com/2/tweets/search/recent +# Docs: https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent +# +# Authentication: Bearer Token (App-only) +# Required env vars: BEARER_TOKEN +# +# Note: Returns posts from the last 7 days. + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +search_url = "https://api.x.com/2/tweets/search/recent" + +# Set the query value here. Value can be up to 512 characters +query = "from:XDevelopers -is:retweet" + +# See docs for list of param options: +# https://developer.x.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent +query_params = { + "query": query, + "max_results": 10, + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields": "description" +} + +def search_posts(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2RecentSearchRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = search_posts(search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/timelines/user_posts.rb b/ruby/timelines/user_posts.rb new file mode 100644 index 0000000..181acf7 --- /dev/null +++ b/ruby/timelines/user_posts.rb @@ -0,0 +1,40 @@ +# User Posts Timeline - X API v2 +# +# Endpoint: GET https://api.x.com/2/users/:id/tweets +# Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-tweets +# +# Authentication: Bearer Token (App-only) or OAuth (User Context) +# Required env vars: BEARER_TOKEN + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +# Replace with the user ID you want to get posts for +user_id = "2244994945" +url = "https://api.x.com/2/users/#{user_id}/tweets" + +query_params = { + "tweet.fields": "created_at,public_metrics", + "max_results": 10 +} + +def get_user_posts(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2UserPostsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_user_posts(url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/followers.rb b/ruby/users/followers.rb new file mode 100644 index 0000000..68a284f --- /dev/null +++ b/ruby/users/followers.rb @@ -0,0 +1,40 @@ +# User Followers Lookup - X API v2 +# +# Endpoint: GET https://api.x.com/2/users/:id/followers +# Docs: https://developer.x.com/en/docs/twitter-api/users/follows/api-reference/get-users-id-followers +# +# Authentication: Bearer Token (App-only) or OAuth (User Context) +# Required env vars: BEARER_TOKEN + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +# Replace with the user ID you want to get followers for +user_id = "2244994945" +url = "https://api.x.com/2/users/#{user_id}/followers" + +query_params = { + "user.fields": "created_at,description", + "max_results": 100 +} + +def get_followers(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2FollowersRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_followers(url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/lookup.rb b/ruby/users/lookup.rb new file mode 100644 index 0000000..c5f3cf9 --- /dev/null +++ b/ruby/users/lookup.rb @@ -0,0 +1,39 @@ +# User Lookup - X API v2 +# +# Endpoint: GET https://api.x.com/2/users/by +# Docs: https://developer.x.com/en/docs/twitter-api/users/lookup/api-reference/get-users-by +# +# Authentication: Bearer Token (App-only) or OAuth (User Context) +# Required env vars: BEARER_TOKEN + +require 'json' +require 'typhoeus' + +bearer_token = ENV["BEARER_TOKEN"] + +url = "https://api.x.com/2/users/by" + +# Usernames to look up (up to 100 comma-separated) +query_params = { + "usernames": "XDevelopers,X", + "user.fields": "created_at,description,public_metrics" +} + +def lookup_users(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2UserLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lookup_users(url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) From 9bd4a77f4958fb5184188534bc75b44323f6df35 Mon Sep 17 00:00:00 2001 From: Santiago Medina Rolong Date: Mon, 1 Dec 2025 11:40:02 -0500 Subject: [PATCH 2/2] more cahnges --- README.md | 141 ++++------- java/posts/FullArchiveSearchDemo.java | 65 +++++ java/posts/FullArchiveTweetCountsDemo.java | 67 +++++ java/posts/QuoteTweetsDemo.java | 64 +++++ java/posts/RecentSearchDemo.java | 65 +++++ java/posts/RecentTweetCountsDemo.java | 66 +++++ java/posts/TweetsDemo.java | 65 +++++ java/spaces/SearchSpacesDemo.java | 66 +++++ java/spaces/SpacesLookupDemo.java | 66 +++++ java/streams/FilteredStreamDemo.java | 183 ++++++++++++++ java/streams/SampledStream.java | 60 +++++ java/timelines/UserMentionsDemo.java | 64 +++++ java/timelines/UserTweetsDemo.java | 64 +++++ .../reverse-chron-home-timeline-java-sdk.java | 130 ++++++++++ java/usage/UsageTweetsDemo.java | 58 +++++ java/users/FollowersLookupDemo.java | 64 +++++ java/users/FollowingLookupDemo.java | 64 +++++ java/users/UsersDemo.java | 66 +++++ .../bookmarks/bookmarks-lookup-js-sdk.js | 92 +++++++ .../bookmarks/create-bookmark-js-sdk.js | 93 +++++++ .../bookmarks/delete-bookmark-js-sdk.js | 91 +++++++ .../compliance/create_compliance_job.js | 47 ++++ .../compliance/download_compliance_results.js | 31 +++ .../get_compliance_job_information_by_id.js | 43 ++++ .../compliance/get_list_of_compliance_jobs.js | 45 ++++ javascript/compliance/upload_ids.js | 40 +++ javascript/lists/List-tweets.js | 47 ++++ javascript/lists/Pinned-List.js | 150 ++++++++++++ javascript/lists/add_member.js | 151 ++++++++++++ javascript/lists/create_a_list.js | 150 ++++++++++++ javascript/lists/delete_a_list.js | 144 +++++++++++ javascript/lists/follow_list.js | 152 ++++++++++++ javascript/lists/list-followers-lookup.js | 47 ++++ javascript/lists/list-lookup-by-id.js | 47 ++++ javascript/lists/list-member-lookup.js | 47 ++++ javascript/lists/pin_list.js | 152 ++++++++++++ javascript/lists/remove_member.js | 149 ++++++++++++ javascript/lists/unfollow_list.js | 149 ++++++++++++ javascript/lists/unpin_list.js | 149 ++++++++++++ javascript/lists/update_a_list.js | 153 ++++++++++++ javascript/lists/user-list-followed.js | 48 ++++ javascript/lists/user-list-memberships.js | 47 ++++ javascript/lists/user-owned-list-lookup.js | 47 ++++ javascript/posts/block_a_user.js | 150 ++++++++++++ javascript/posts/create_tweet.js | 144 +++++++++++ javascript/posts/delete_tweet.js | 142 +++++++++++ javascript/posts/full-archive-search.js | 51 ++++ javascript/posts/full_archive_tweet_counts.js | 51 ++++ .../posts/get_tweets_with_bearer_token.js | 53 ++++ .../posts/get_tweets_with_user_context.js | 150 ++++++++++++ javascript/posts/like_a_tweet.js | 148 +++++++++++ javascript/posts/liked_tweets.js | 46 ++++ javascript/posts/liking_users.js | 49 ++++ javascript/posts/quote_tweets.js | 74 ++++++ javascript/posts/recent_search.js | 51 ++++ javascript/posts/recent_tweet_counts.js | 50 ++++ javascript/posts/retweet_a_tweet.js | 148 +++++++++++ javascript/posts/retweeted_by.js | 49 ++++ javascript/posts/unblock_a_user.js | 149 ++++++++++++ javascript/posts/undo_a_retweet.js | 145 +++++++++++ javascript/posts/unlike_a_tweet.js | 145 +++++++++++ javascript/spaces/search_spaces.js | 51 ++++ javascript/spaces/spaces_lookup.js | 50 ++++ javascript/streams/filtered_stream.js | 128 ++++++---- javascript/streams/sampled_stream.js | 60 +++++ .../reverse-chron-home-timeline-js-sdk.js | 92 +++++++ .../timelines/reverse-chron-home-timeline.js | 142 +++++++++++ javascript/timelines/user_mentions.js | 74 ++++++ javascript/timelines/user_tweets.js | 79 ++++++ javascript/usage/get_usage_tweets.js | 44 ++++ javascript/users/followers_lookup.js | 67 +++++ javascript/users/following_lookup.js | 67 +++++ .../users/get_users_me_with_user_context.js | 146 +++++++++++ .../users/get_users_with_bearer_token.js | 53 ++++ .../users/get_users_with_user_context.js | 150 ++++++++++++ javascript/users/lookup_blocks.js | 140 +++++++++++ javascript/users/lookup_mutes.js | 142 +++++++++++ javascript/users/mute_a_user.js | 150 ++++++++++++ javascript/users/unmute_a_user.js | 145 +++++++++++ python/README.md | 221 +++++++++-------- python/bookmarks/bookmarks_lookup.py | 103 ++++++++ python/bookmarks/create_bookmark.py | 107 ++++++++ python/bookmarks/delete_bookmark.py | 109 +++++++++ python/compliance/create_compliance_job.py | 40 +++ .../compliance/download_compliance_results.py | 23 ++ .../get_compliance_job_information_by_id.py | 39 +++ .../compliance/get_list_of_compliance_jobs.py | 39 +++ python/compliance/upload_ids.py | 26 ++ .../get_events_by_conversation.py | 107 ++++++++ .../get_one_to_one_conversation_events.py | 108 +++++++++ .../get_user_conversation_events.py | 102 ++++++++ .../post_dm_to_conversation.py | 113 +++++++++ .../post_group_conversation_dm.py | 116 +++++++++ python/direct_messages/post_one_to_one_dm.py | 114 +++++++++ python/lists/List-Tweets.py | 55 +++++ python/lists/Pinned-List.py | 78 ++++++ python/lists/add_member.py | 77 ++++++ python/lists/create_a_list.py | 76 ++++++ python/lists/delete_a_list.py | 75 ++++++ python/lists/follow_list.py | 77 ++++++ python/lists/list-followers-lookup.py | 51 ++++ python/lists/list-lookup-by-id.py | 50 ++++ python/lists/list-member-lookup.py | 50 ++++ python/lists/pin_list.py | 77 ++++++ python/lists/remove_member.py | 78 ++++++ python/lists/unfollow_list.py | 78 ++++++ python/lists/unpin_list.py | 78 ++++++ python/lists/update_a_list.py | 81 +++++++ python/lists/user-list-followed.py | 50 ++++ python/lists/user-list-memberships.py | 50 ++++ python/lists/user-owned-list-lookup.py | 50 ++++ python/media/media_upload_v2.py | 229 ++++++++++++++++++ python/posts/create_tweet.py | 73 ++++++ python/posts/delete_tweet.py | 73 ++++++ python/posts/full-archive-search.py | 40 +++ python/posts/full_archive_tweet_counts.py | 39 +++ python/posts/get_tweets_with_bearer_token.py | 55 +++++ python/posts/get_tweets_with_user_context.py | 77 ++++++ python/posts/like_a_tweet.py | 77 ++++++ python/posts/liked_tweets.py | 58 +++++ python/posts/liking_users.py | 47 ++-- python/posts/quote_tweets.py | 58 +++++ python/posts/recent_search.py | 39 +++ python/posts/recent_tweet_counts.py | 39 +++ python/posts/retweet_a_tweet.py | 78 ++++++ python/posts/retweeted_by.py | 56 +++++ python/posts/undo_a_retweet.py | 79 ++++++ python/posts/unlike_a_tweet.py | 77 ++++++ python/requirements.txt | 8 - python/spaces/search_spaces.py | 40 +++ python/spaces/spaces_lookup.py | 38 +++ python/streams/filtered_stream.py | 21 +- python/streams/sampled-stream.py | 48 ++++ .../timelines/reverse-chron-home-timeline.py | 112 +++++++++ python/timelines/user_mentions.py | 31 ++- python/timelines/user_tweets.py | 57 +++++ python/usage/get_usage_tweets.py | 38 +++ python/users/block_a_user.py | 77 ++++++ python/users/followers_lookup.py | 50 ++++ python/users/following_lookup.py | 50 ++++ python/users/get_users_me_user_context.py | 73 ++++++ python/users/get_users_with_bearer_token.py | 52 ++++ python/users/get_users_with_user_context.py | 75 ++++++ python/users/lookup_blocks.py | 77 ++++++ python/users/lookup_mutes.py | 79 ++++++ python/users/mute_a_user.py | 77 ++++++ python/users/unblock_a_user.py | 81 +++++++ python/users/unmute_a_user.py | 79 ++++++ r/posts/full-archive-search.r | 26 ++ r/posts/full_archive_tweet_counts.r | 25 ++ r/posts/recent-search.r | 28 +++ r/posts/recent_tweet_counts.r | 25 ++ r/users/get_users_with_bearer_token.r | 20 ++ ruby/Gemfile | 6 - ruby/bookmarks/bookmarks_lookup.rb | 110 +++++++++ ruby/lists/List-Tweets.rb | 44 ++++ ruby/lists/Pinned-List.rb | 89 +++++++ ruby/lists/add_member.rb | 84 +++++++ ruby/lists/create_a_list.rb | 86 +++++++ ruby/lists/delete_a_list.rb | 83 +++++++ ruby/lists/follow_list.rb | 85 +++++++ ruby/lists/list-followers-lookup.rb | 41 ++++ ruby/lists/list-lookup-by-id.rb | 40 +++ ruby/lists/list-member-lookup.rb | 41 ++++ ruby/lists/pin_list.rb | 85 +++++++ ruby/lists/remove_member.rb | 83 +++++++ ruby/lists/unfollow_list.rb | 81 +++++++ ruby/lists/unpin_list.rb | 81 +++++++ ruby/lists/update_a_list.rb | 89 +++++++ ruby/lists/user-list-followed.rb | 40 +++ ruby/lists/user-list-memberships.rb | 40 +++ ruby/lists/user-owned-list-lookup.rb | 40 +++ ruby/posts/create_tweet.rb | 82 +++++++ ruby/posts/delete_tweet.rb | 79 ++++++ ruby/posts/full-archive-search.rb | 49 ++++ ruby/posts/full_archive_tweet_counts.rb | 42 ++++ ruby/posts/get_tweets_with_bearer_token.rb | 45 ++++ ruby/posts/get_tweets_with_user_context.rb | 91 +++++++ ruby/posts/like_a_tweet.rb | 86 +++++++ ruby/posts/liked_tweets.rb | 45 ++++ ruby/posts/liking_users.rb | 43 ++++ ruby/posts/quote_tweets.rb | 44 ++++ ruby/posts/recent_search.rb | 49 ++++ ruby/posts/recent_tweet_counts.rb | 41 ++++ ruby/posts/retweet_a_tweet.rb | 86 +++++++ ruby/posts/retweeted_by.rb | 43 ++++ ruby/posts/undo_a_retweet.rb | 84 +++++++ ruby/posts/unlike_a_tweet.rb | 84 +++++++ ruby/spaces/search_spaces.rb | 42 ++++ ruby/spaces/spaces_lookup.rb | 42 ++++ ruby/streams/filtered_stream.rb | 144 +++++++++++ ruby/streams/sampled_stream.rb | 51 ++++ ruby/timelines/reverse-chron-home-timeline.rb | 110 +++++++++ ruby/timelines/user-mentions.rb | 49 ++++ ruby/timelines/user-tweets.rb | 55 +++++ ruby/users/block_a_user.rb | 86 +++++++ ruby/users/followers-lookup.rb | 40 +++ ruby/users/following-lookup.rb | 40 +++ ruby/users/get_users_me_with_user_context.rb | 80 ++++++ ruby/users/get_users_with_bearer_token.rb | 44 ++++ ruby/users/get_users_with_user_context.rb | 88 +++++++ ruby/users/lookup_blocks.rb | 81 +++++++ ruby/users/lookup_mutes.rb | 81 +++++++ ruby/users/mute_a_user.rb | 85 +++++++ ruby/users/unblock_a_user.rb | 86 +++++++ ruby/users/unmute_a_user.rb | 82 +++++++ 206 files changed, 15497 insertions(+), 313 deletions(-) create mode 100644 java/posts/FullArchiveSearchDemo.java create mode 100644 java/posts/FullArchiveTweetCountsDemo.java create mode 100644 java/posts/QuoteTweetsDemo.java create mode 100644 java/posts/RecentSearchDemo.java create mode 100644 java/posts/RecentTweetCountsDemo.java create mode 100644 java/posts/TweetsDemo.java create mode 100644 java/spaces/SearchSpacesDemo.java create mode 100644 java/spaces/SpacesLookupDemo.java create mode 100644 java/streams/FilteredStreamDemo.java create mode 100644 java/streams/SampledStream.java create mode 100644 java/timelines/UserMentionsDemo.java create mode 100644 java/timelines/UserTweetsDemo.java create mode 100644 java/timelines/reverse-chron-home-timeline-java-sdk.java create mode 100644 java/usage/UsageTweetsDemo.java create mode 100644 java/users/FollowersLookupDemo.java create mode 100644 java/users/FollowingLookupDemo.java create mode 100644 java/users/UsersDemo.java create mode 100644 javascript/bookmarks/bookmarks-lookup-js-sdk.js create mode 100644 javascript/bookmarks/create-bookmark-js-sdk.js create mode 100644 javascript/bookmarks/delete-bookmark-js-sdk.js create mode 100644 javascript/compliance/create_compliance_job.js create mode 100644 javascript/compliance/download_compliance_results.js create mode 100644 javascript/compliance/get_compliance_job_information_by_id.js create mode 100644 javascript/compliance/get_list_of_compliance_jobs.js create mode 100644 javascript/compliance/upload_ids.js create mode 100644 javascript/lists/List-tweets.js create mode 100644 javascript/lists/Pinned-List.js create mode 100644 javascript/lists/add_member.js create mode 100644 javascript/lists/create_a_list.js create mode 100644 javascript/lists/delete_a_list.js create mode 100644 javascript/lists/follow_list.js create mode 100644 javascript/lists/list-followers-lookup.js create mode 100644 javascript/lists/list-lookup-by-id.js create mode 100644 javascript/lists/list-member-lookup.js create mode 100644 javascript/lists/pin_list.js create mode 100644 javascript/lists/remove_member.js create mode 100644 javascript/lists/unfollow_list.js create mode 100644 javascript/lists/unpin_list.js create mode 100644 javascript/lists/update_a_list.js create mode 100644 javascript/lists/user-list-followed.js create mode 100644 javascript/lists/user-list-memberships.js create mode 100644 javascript/lists/user-owned-list-lookup.js create mode 100644 javascript/posts/block_a_user.js create mode 100644 javascript/posts/create_tweet.js create mode 100644 javascript/posts/delete_tweet.js create mode 100644 javascript/posts/full-archive-search.js create mode 100644 javascript/posts/full_archive_tweet_counts.js create mode 100644 javascript/posts/get_tweets_with_bearer_token.js create mode 100644 javascript/posts/get_tweets_with_user_context.js create mode 100644 javascript/posts/like_a_tweet.js create mode 100644 javascript/posts/liked_tweets.js create mode 100644 javascript/posts/liking_users.js create mode 100644 javascript/posts/quote_tweets.js create mode 100644 javascript/posts/recent_search.js create mode 100644 javascript/posts/recent_tweet_counts.js create mode 100644 javascript/posts/retweet_a_tweet.js create mode 100644 javascript/posts/retweeted_by.js create mode 100644 javascript/posts/unblock_a_user.js create mode 100644 javascript/posts/undo_a_retweet.js create mode 100644 javascript/posts/unlike_a_tweet.js create mode 100644 javascript/spaces/search_spaces.js create mode 100644 javascript/spaces/spaces_lookup.js create mode 100644 javascript/streams/sampled_stream.js create mode 100644 javascript/timelines/reverse-chron-home-timeline-js-sdk.js create mode 100644 javascript/timelines/reverse-chron-home-timeline.js create mode 100644 javascript/timelines/user_mentions.js create mode 100644 javascript/timelines/user_tweets.js create mode 100644 javascript/usage/get_usage_tweets.js create mode 100644 javascript/users/followers_lookup.js create mode 100644 javascript/users/following_lookup.js create mode 100644 javascript/users/get_users_me_with_user_context.js create mode 100644 javascript/users/get_users_with_bearer_token.js create mode 100644 javascript/users/get_users_with_user_context.js create mode 100644 javascript/users/lookup_blocks.js create mode 100644 javascript/users/lookup_mutes.js create mode 100644 javascript/users/mute_a_user.js create mode 100644 javascript/users/unmute_a_user.js create mode 100644 python/bookmarks/bookmarks_lookup.py create mode 100644 python/bookmarks/create_bookmark.py create mode 100644 python/bookmarks/delete_bookmark.py create mode 100644 python/compliance/create_compliance_job.py create mode 100644 python/compliance/download_compliance_results.py create mode 100644 python/compliance/get_compliance_job_information_by_id.py create mode 100644 python/compliance/get_list_of_compliance_jobs.py create mode 100644 python/compliance/upload_ids.py create mode 100644 python/direct_messages/get_events_by_conversation.py create mode 100644 python/direct_messages/get_one_to_one_conversation_events.py create mode 100644 python/direct_messages/get_user_conversation_events.py create mode 100644 python/direct_messages/post_dm_to_conversation.py create mode 100644 python/direct_messages/post_group_conversation_dm.py create mode 100644 python/direct_messages/post_one_to_one_dm.py create mode 100644 python/lists/List-Tweets.py create mode 100644 python/lists/Pinned-List.py create mode 100644 python/lists/add_member.py create mode 100644 python/lists/create_a_list.py create mode 100644 python/lists/delete_a_list.py create mode 100644 python/lists/follow_list.py create mode 100644 python/lists/list-followers-lookup.py create mode 100644 python/lists/list-lookup-by-id.py create mode 100644 python/lists/list-member-lookup.py create mode 100644 python/lists/pin_list.py create mode 100644 python/lists/remove_member.py create mode 100644 python/lists/unfollow_list.py create mode 100644 python/lists/unpin_list.py create mode 100644 python/lists/update_a_list.py create mode 100644 python/lists/user-list-followed.py create mode 100644 python/lists/user-list-memberships.py create mode 100644 python/lists/user-owned-list-lookup.py create mode 100644 python/media/media_upload_v2.py create mode 100644 python/posts/create_tweet.py create mode 100644 python/posts/delete_tweet.py create mode 100644 python/posts/full-archive-search.py create mode 100644 python/posts/full_archive_tweet_counts.py create mode 100644 python/posts/get_tweets_with_bearer_token.py create mode 100644 python/posts/get_tweets_with_user_context.py create mode 100644 python/posts/like_a_tweet.py create mode 100644 python/posts/liked_tweets.py create mode 100644 python/posts/quote_tweets.py create mode 100644 python/posts/recent_search.py create mode 100644 python/posts/recent_tweet_counts.py create mode 100644 python/posts/retweet_a_tweet.py create mode 100644 python/posts/retweeted_by.py create mode 100644 python/posts/undo_a_retweet.py create mode 100644 python/posts/unlike_a_tweet.py create mode 100644 python/spaces/search_spaces.py create mode 100644 python/spaces/spaces_lookup.py create mode 100644 python/streams/sampled-stream.py create mode 100644 python/timelines/reverse-chron-home-timeline.py create mode 100644 python/timelines/user_tweets.py create mode 100644 python/usage/get_usage_tweets.py create mode 100644 python/users/block_a_user.py create mode 100644 python/users/followers_lookup.py create mode 100644 python/users/following_lookup.py create mode 100644 python/users/get_users_me_user_context.py create mode 100644 python/users/get_users_with_bearer_token.py create mode 100644 python/users/get_users_with_user_context.py create mode 100644 python/users/lookup_blocks.py create mode 100644 python/users/lookup_mutes.py create mode 100644 python/users/mute_a_user.py create mode 100644 python/users/unblock_a_user.py create mode 100644 python/users/unmute_a_user.py create mode 100644 r/posts/full-archive-search.r create mode 100644 r/posts/full_archive_tweet_counts.r create mode 100644 r/posts/recent-search.r create mode 100644 r/posts/recent_tweet_counts.r create mode 100644 r/users/get_users_with_bearer_token.r create mode 100644 ruby/bookmarks/bookmarks_lookup.rb create mode 100644 ruby/lists/List-Tweets.rb create mode 100644 ruby/lists/Pinned-List.rb create mode 100644 ruby/lists/add_member.rb create mode 100644 ruby/lists/create_a_list.rb create mode 100644 ruby/lists/delete_a_list.rb create mode 100644 ruby/lists/follow_list.rb create mode 100644 ruby/lists/list-followers-lookup.rb create mode 100644 ruby/lists/list-lookup-by-id.rb create mode 100644 ruby/lists/list-member-lookup.rb create mode 100644 ruby/lists/pin_list.rb create mode 100644 ruby/lists/remove_member.rb create mode 100644 ruby/lists/unfollow_list.rb create mode 100644 ruby/lists/unpin_list.rb create mode 100644 ruby/lists/update_a_list.rb create mode 100644 ruby/lists/user-list-followed.rb create mode 100644 ruby/lists/user-list-memberships.rb create mode 100644 ruby/lists/user-owned-list-lookup.rb create mode 100644 ruby/posts/create_tweet.rb create mode 100644 ruby/posts/delete_tweet.rb create mode 100644 ruby/posts/full-archive-search.rb create mode 100644 ruby/posts/full_archive_tweet_counts.rb create mode 100644 ruby/posts/get_tweets_with_bearer_token.rb create mode 100644 ruby/posts/get_tweets_with_user_context.rb create mode 100644 ruby/posts/like_a_tweet.rb create mode 100644 ruby/posts/liked_tweets.rb create mode 100644 ruby/posts/liking_users.rb create mode 100644 ruby/posts/quote_tweets.rb create mode 100644 ruby/posts/recent_search.rb create mode 100644 ruby/posts/recent_tweet_counts.rb create mode 100644 ruby/posts/retweet_a_tweet.rb create mode 100644 ruby/posts/retweeted_by.rb create mode 100644 ruby/posts/undo_a_retweet.rb create mode 100644 ruby/posts/unlike_a_tweet.rb create mode 100644 ruby/spaces/search_spaces.rb create mode 100644 ruby/spaces/spaces_lookup.rb create mode 100644 ruby/streams/filtered_stream.rb create mode 100644 ruby/streams/sampled_stream.rb create mode 100644 ruby/timelines/reverse-chron-home-timeline.rb create mode 100644 ruby/timelines/user-mentions.rb create mode 100644 ruby/timelines/user-tweets.rb create mode 100644 ruby/users/block_a_user.rb create mode 100644 ruby/users/followers-lookup.rb create mode 100644 ruby/users/following-lookup.rb create mode 100644 ruby/users/get_users_me_with_user_context.rb create mode 100644 ruby/users/get_users_with_bearer_token.rb create mode 100644 ruby/users/get_users_with_user_context.rb create mode 100644 ruby/users/lookup_blocks.rb create mode 100644 ruby/users/lookup_mutes.rb create mode 100644 ruby/users/mute_a_user.rb create mode 100644 ruby/users/unblock_a_user.rb create mode 100644 ruby/users/unmute_a_user.rb diff --git a/README.md b/README.md index c7dbd72..b1fbeff 100644 --- a/README.md +++ b/README.md @@ -2,15 +2,16 @@ [![X API v2](https://img.shields.io/endpoint?url=https%3A%2F%2Ftwbadges.glitch.me%2Fbadges%2Fv2)](https://developer.x.com/en/docs/twitter-api) -Working code samples for the **X (formerly Twitter) API v2** in Python, JavaScript, Ruby, and Java. +Working code samples for the **X API v2** in Python, JavaScript, Ruby, Java, and R. ## 📁 Repository Structure ``` -├── python/ # Python examples (most complete) -├── javascript/ # JavaScript (Node.js) examples -├── ruby/ # Ruby examples -├── java/ # Java examples +├── python/ # 108 Python examples +├── javascript/ # 70 JavaScript examples +├── ruby/ # 58 Ruby examples +├── java/ # 19 Java examples +├── r/ # 5 R examples ├── llms.txt # LLM-friendly documentation └── api-index.json # Machine-readable endpoint catalog ``` @@ -19,110 +20,66 @@ Working code samples for the **X (formerly Twitter) API v2** in Python, JavaScri ### 1. Get API Credentials -Sign up at the [X Developer Portal](https://developer.x.com/en/portal/dashboard) and create a project/app. +Sign up at the [X Developer Portal](https://developer.x.com/en/portal/dashboard). ### 2. Set Environment Variables ```bash -# For app-only authentication (read-only endpoints) export BEARER_TOKEN='your_bearer_token' - -# For user context authentication (actions on behalf of users) export CONSUMER_KEY='your_consumer_key' export CONSUMER_SECRET='your_consumer_secret' ``` -### 3. Choose Your Language - -| Language | Setup | Run Example | -|----------|-------|-------------| -| **Python** | `pip install -r python/requirements.txt` | `python python/posts/search_recent.py` | -| **JavaScript** | `cd javascript && npm install` | `node javascript/posts/search_recent.js` | -| **Ruby** | `gem install typhoeus` | `ruby ruby/posts/search_recent.rb` | -| **Java** | Add dependencies (see java/README.md) | `javac && java SearchRecent` | - -## 📚 Available Examples - -### Posts (formerly Tweets) - -| Operation | Python | JavaScript | Ruby | Java | -|-----------|--------|------------|------|------| -| Create Post | ✅ | ✅ | | | -| Delete Post | ✅ | ✅ | | | -| Lookup Posts | ✅ | ✅ | ✅ | | -| Search Recent | ✅ | ✅ | ✅ | ✅ | -| Search Full Archive | ✅ | | | | -| Post Counts | ✅ | | | | -| Quote Posts | ✅ | | | | -| Repost | ✅ | | | | -| Like/Unlike | ✅ | | | | - -### Users - -| Operation | Python | JavaScript | Ruby | Java | -|-----------|--------|------------|------|------| -| Lookup Users | ✅ | ✅ | ✅ | ✅ | -| Get Me | ✅ | | | | -| Followers | ✅ | ✅ | ✅ | | -| Following | ✅ | | | | -| Block/Unblock | ✅ | | | | -| Mute/Unmute | ✅ | | | | - -### Timelines - -| Operation | Python | JavaScript | Ruby | -|-----------|--------|------------|------| -| User Posts | ✅ | ✅ | ✅ | -| User Mentions | ✅ | | | -| Home Timeline | ✅ | | | - -### Streams - -| Operation | Python | JavaScript | -|-----------|--------|------------| -| Filtered Stream | ✅ | ✅ | -| Sampled Stream | ✅ | | - -### Other - -| Category | Python | JavaScript | Ruby | -|----------|--------|------------|------| -| Bookmarks | ✅ | | | -| Spaces | ✅ | ✅ | | -| Lists | ✅ | ✅ | ✅ | -| Direct Messages | ✅ | | | -| Media Upload | ✅ | | | -| Compliance | ✅ | | | -| Usage Stats | ✅ | | | - -## 🔐 Authentication Types - -| Type | Use Case | Required Env Vars | -|------|----------|-------------------| -| **Bearer Token** | Read-only endpoints (search, lookup) | `BEARER_TOKEN` | -| **OAuth 1.0a** | User actions (post, like, follow) | `CONSUMER_KEY`, `CONSUMER_SECRET` | -| **OAuth 2.0 PKCE** | Newer endpoints (bookmarks) | OAuth flow required | +### 3. Run an Example -## 🔗 Resources +```bash +# Python +cd python && pip install -r requirements.txt +python posts/recent_search.py -- [X API Documentation](https://developer.x.com/en/docs/twitter-api) -- [Developer Portal](https://developer.x.com/en/portal/dashboard) -- [API Reference Index](https://developer.x.com/en/docs/api-reference-index) -- [Postman Collection](https://t.co/twitter-api-postman) +# JavaScript +cd javascript && npm install +node posts/recent_search.js + +# Ruby +cd ruby && bundle install +ruby posts/recent_search.rb +``` + +## 📚 Examples by Category + +| Category | Python | JavaScript | Ruby | Java | R | +|----------|--------|------------|------|------|---| +| Posts (search, create, delete, likes, retweets) | ✅ | ✅ | ✅ | ✅ | ✅ | +| Users (lookup, followers, blocks, mutes) | ✅ | ✅ | ✅ | ✅ | ✅ | +| Timelines (user, mentions, home) | ✅ | ✅ | ✅ | ✅ | | +| Streams (filtered, sampled) | ✅ | ✅ | ✅ | ✅ | | +| Lists (lookup, manage, members) | ✅ | ✅ | ✅ | | | +| Spaces (lookup, search) | ✅ | ✅ | ✅ | ✅ | | +| Bookmarks | ✅ | ✅ | ✅ | | | +| Direct Messages | ✅ | | | | | +| Media Upload | ✅ | | | | | +| Compliance | ✅ | ✅ | | ✅ | | +| Usage | ✅ | ✅ | | ✅ | | + +## 🔐 Authentication + +| Type | Use Case | Env Vars | +|------|----------|----------| +| Bearer Token | Read-only (search, lookup) | `BEARER_TOKEN` | +| OAuth 1.0a | User actions (post, like) | `CONSUMER_KEY`, `CONSUMER_SECRET` | +| OAuth 2.0 PKCE | Bookmarks, newer endpoints | OAuth flow | ## 🤖 For LLMs -This repository includes: -- **`llms.txt`** - Comprehensive context file for AI assistants +- **`llms.txt`** - Context file for AI assistants - **`api-index.json`** - Machine-readable endpoint catalog -## 🤝 Contributing +## 🔗 Resources -We welcome contributions! Please: -1. Follow existing code patterns -2. Include proper documentation headers -3. Test your examples before submitting +- [X API Documentation](https://developer.x.com/en/docs/twitter-api) +- [Developer Portal](https://developer.x.com/en/portal/dashboard) ## 📄 License -Apache 2.0 - See [LICENSE](LICENSE) +Apache 2.0 diff --git a/java/posts/FullArchiveSearchDemo.java b/java/posts/FullArchiveSearchDemo.java new file mode 100644 index 0000000..9f058c2 --- /dev/null +++ b/java/posts/FullArchiveSearchDemo.java @@ -0,0 +1,65 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Full archive search endpoint + * */ +public class FullArchiveSearchDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace the search term with a term of your choice + String response = search("from:TwitterDev OR from:SnowBotDev OR from:DailyNASA", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the full-archive search endpoint with a the search term passed to it as a query parameter + * */ + private static String search(String searchString, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/all"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("query", searchString)); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/posts/FullArchiveTweetCountsDemo.java b/java/posts/FullArchiveTweetCountsDemo.java new file mode 100644 index 0000000..65bb037 --- /dev/null +++ b/java/posts/FullArchiveTweetCountsDemo.java @@ -0,0 +1,67 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Full-archive Tweet counts endpoint + * */ +public class FullArchiveTweetCountsDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace the search term with a term of your choice + String response = getTweetCounts("from:TwitterDev", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the full-archive Tweet counts endpoint with a the search term passed to it as a query parameter + * */ + private static String getTweetCounts(String searchString, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/counts/all"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("query", searchString)); + queryParameters.add(new BasicNameValuePair("granularity", "day")); + queryParameters.add(new BasicNameValuePair("start_time", "2021-01-01T00:00:00Z")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/posts/QuoteTweetsDemo.java b/java/posts/QuoteTweetsDemo.java new file mode 100644 index 0000000..e9fc858 --- /dev/null +++ b/java/posts/QuoteTweetsDemo.java @@ -0,0 +1,64 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 Quote Tweets endpoint + * */ +public class QuoteTweetsDemo { + + // To set your environment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + final String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace with Tweet ID below + String response = getTweets(20, bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 Quote Tweets endpoint by Tweet ID + * */ + private static String getTweets(int tweetId, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(String.format("https://api.x.com/2/tweets/%s/quote_tweets", tweetId)); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} diff --git a/java/posts/RecentSearchDemo.java b/java/posts/RecentSearchDemo.java new file mode 100644 index 0000000..e504b46 --- /dev/null +++ b/java/posts/RecentSearchDemo.java @@ -0,0 +1,65 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Recent search endpoint + * */ +public class RecentSearchDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace the search term with a term of your choice + String response = search("from:TwitterDev OR from:SnowBotDev OR from:DailyNASA", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the recent search endpoint with a the search term passed to it as a query parameter + * */ + private static String search(String searchString, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/recent"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("query", searchString)); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/posts/RecentTweetCountsDemo.java b/java/posts/RecentTweetCountsDemo.java new file mode 100644 index 0000000..1735b9c --- /dev/null +++ b/java/posts/RecentTweetCountsDemo.java @@ -0,0 +1,66 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Recent Tweet counts endpoint + * */ +public class RecentTweetCountsDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace the search term with a term of your choice + String response = getTweetCounts("from:TwitterDev", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the recent Tweet counts endpoint with a the search term passed to it as a query parameter + * */ + private static String getTweetCounts(String searchString, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/counts/recent"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("query", searchString)); + queryParameters.add(new BasicNameValuePair("granularity", "day")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/posts/TweetsDemo.java b/java/posts/TweetsDemo.java new file mode 100644 index 0000000..60c41e6 --- /dev/null +++ b/java/posts/TweetsDemo.java @@ -0,0 +1,65 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 Tweets endpoint + * */ +public class TweetsDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace comma separated ids with Tweets Ids of your choice + String response = getTweets("1138505981460193280,1261326399320715264", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 Tweets endpoint with ids as query parameter + * */ + private static String getTweets(String ids, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("ids", ids)); + queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} \ No newline at end of file diff --git a/java/spaces/SearchSpacesDemo.java b/java/spaces/SearchSpacesDemo.java new file mode 100644 index 0000000..2e92b2a --- /dev/null +++ b/java/spaces/SearchSpacesDemo.java @@ -0,0 +1,66 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Spaces lookup endpoint + * */ +public class SpacesLookupDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace SPACE_ID with the ID of a Space + String response = getSpaceById("SPACE_ID", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the Spaces lookup endpoint with the ID passed to it as a query parameter + * */ + private static String getSpaceById(String spaceId, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/spaces"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("ids", spaceId)); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("User-Agent", "v2SpacesLookupJava"); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/spaces/SpacesLookupDemo.java b/java/spaces/SpacesLookupDemo.java new file mode 100644 index 0000000..2e92b2a --- /dev/null +++ b/java/spaces/SpacesLookupDemo.java @@ -0,0 +1,66 @@ +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +/* + * Sample code to demonstrate the use of the Spaces lookup endpoint + * */ +public class SpacesLookupDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace SPACE_ID with the ID of a Space + String response = getSpaceById("SPACE_ID", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the Spaces lookup endpoint with the ID passed to it as a query parameter + * */ + private static String getSpaceById(String spaceId, String bearerToken) throws IOException, URISyntaxException { + String searchResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/spaces"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("ids", spaceId)); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("User-Agent", "v2SpacesLookupJava"); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + searchResponse = EntityUtils.toString(entity, "UTF-8"); + } + return searchResponse; + } + +} \ No newline at end of file diff --git a/java/streams/FilteredStreamDemo.java b/java/streams/FilteredStreamDemo.java new file mode 100644 index 0000000..6a30c85 --- /dev/null +++ b/java/streams/FilteredStreamDemo.java @@ -0,0 +1,183 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.*; +import java.net.URISyntaxException; +import java.util.*; + +/* + * Sample code to demonstrate the use of the Filtered Stream endpoint + * */ +public class FilteredStreamDemo { + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + Map rules = new HashMap<>(); + rules.put("cats has:images", "cat images"); + rules.put("dogs has:images", "dog images"); + setupRules(bearerToken, rules); + connectStream(bearerToken); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the filtered stream endpoint and streams Tweets from it + * */ + private static void connectStream(String bearerToken) throws IOException, URISyntaxException { + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/stream"); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + BufferedReader reader = new BufferedReader(new InputStreamReader((entity.getContent()))); + String line = reader.readLine(); + while (line != null) { + System.out.println(line); + line = reader.readLine(); + } + } + + } + + /* + * Helper method to setup rules before streaming data + * */ + private static void setupRules(String bearerToken, Map rules) throws IOException, URISyntaxException { + List existingRules = getRules(bearerToken); + if (existingRules.size() > 0) { + deleteRules(bearerToken, existingRules); + } + createRules(bearerToken, rules); + } + + /* + * Helper method to create rules for filtering + * */ + private static void createRules(String bearerToken, Map rules) throws URISyntaxException, IOException { + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/stream/rules"); + + HttpPost httpPost = new HttpPost(uriBuilder.build()); + httpPost.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpPost.setHeader("content-type", "application/json"); + StringEntity body = new StringEntity(getFormattedString("{\"add\": [%s]}", rules)); + httpPost.setEntity(body); + HttpResponse response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + if (null != entity) { + System.out.println(EntityUtils.toString(entity, "UTF-8")); + } + } + + /* + * Helper method to get existing rules + * */ + private static List getRules(String bearerToken) throws URISyntaxException, IOException { + List rules = new ArrayList<>(); + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/stream/rules"); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("content-type", "application/json"); + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + JSONObject json = new JSONObject(EntityUtils.toString(entity, "UTF-8")); + if (json.length() > 1) { + JSONArray array = (JSONArray) json.get("data"); + for (int i = 0; i < array.length(); i++) { + JSONObject jsonObject = (JSONObject) array.get(i); + rules.add(jsonObject.getString("id")); + } + } + } + return rules; + } + + /* + * Helper method to delete rules + * */ + private static void deleteRules(String bearerToken, List existingRules) throws URISyntaxException, IOException { + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/search/stream/rules"); + + HttpPost httpPost = new HttpPost(uriBuilder.build()); + httpPost.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpPost.setHeader("content-type", "application/json"); + StringEntity body = new StringEntity(getFormattedString("{ \"delete\": { \"ids\": [%s]}}", existingRules)); + httpPost.setEntity(body); + HttpResponse response = httpClient.execute(httpPost); + HttpEntity entity = response.getEntity(); + if (null != entity) { + System.out.println(EntityUtils.toString(entity, "UTF-8")); + } + } + + private static String getFormattedString(String string, List ids) { + StringBuilder sb = new StringBuilder(); + if (ids.size() == 1) { + return String.format(string, "\"" + ids.get(0) + "\""); + } else { + for (String id : ids) { + sb.append("\"" + id + "\"" + ","); + } + String result = sb.toString(); + return String.format(string, result.substring(0, result.length() - 1)); + } + } + + private static String getFormattedString(String string, Map rules) { + StringBuilder sb = new StringBuilder(); + if (rules.size() == 1) { + String key = rules.keySet().iterator().next(); + return String.format(string, "{\"value\": \"" + key + "\", \"tag\": \"" + rules.get(key) + "\"}"); + } else { + for (Map.Entry entry : rules.entrySet()) { + String value = entry.getKey(); + String tag = entry.getValue(); + sb.append("{\"value\": \"" + value + "\", \"tag\": \"" + tag + "\"}" + ","); + } + String result = sb.toString(); + return String.format(string, result.substring(0, result.length() - 1)); + } + } + +} diff --git a/java/streams/SampledStream.java b/java/streams/SampledStream.java new file mode 100644 index 0000000..4d0444e --- /dev/null +++ b/java/streams/SampledStream.java @@ -0,0 +1,60 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URISyntaxException; + +/* + * Sample code to demonstrate the use of the Sampled Stream endpoint + * */ +public class SampledStreamDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + connectStream(bearerToken); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + + } + + /* + * This method calls the sample stream endpoint and streams Tweets from it + * */ + private static void connectStream(String bearerToken) throws IOException, URISyntaxException { + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/tweets/sample/stream"); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + BufferedReader reader = new BufferedReader(new InputStreamReader((entity.getContent()))); + String line = reader.readLine(); + while (line != null) { + System.out.println(line); + line = reader.readLine(); + } + } + + } +} diff --git a/java/timelines/UserMentionsDemo.java b/java/timelines/UserMentionsDemo.java new file mode 100644 index 0000000..efff5a3 --- /dev/null +++ b/java/timelines/UserMentionsDemo.java @@ -0,0 +1,64 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 User Mentions timeline endpoint + * */ +public class UserMentionsDemo { + + // To set your environment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + final String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace with user ID below + String response = getTweets("2244994945", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 User Mentions timeline endpoint by user ID + * */ + private static String getTweets(String userId, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(String.format("https://api.x.com/2/users/%s/mentions", userId)); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} diff --git a/java/timelines/UserTweetsDemo.java b/java/timelines/UserTweetsDemo.java new file mode 100644 index 0000000..d0b1edb --- /dev/null +++ b/java/timelines/UserTweetsDemo.java @@ -0,0 +1,64 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 User Tweet timeline endpoint + * */ +public class UserTweetsDemo { + + // To set your environment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + final String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + // Replace with user ID below + String response = getTweets("2244994945", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 User Tweet timeline endpoint by user ID + * */ + private static String getTweets(String userId, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(String.format("https://api.x.com/2/users/%s/tweets", userId)); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("tweet.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} diff --git a/java/timelines/reverse-chron-home-timeline-java-sdk.java b/java/timelines/reverse-chron-home-timeline-java-sdk.java new file mode 100644 index 0000000..4605598 --- /dev/null +++ b/java/timelines/reverse-chron-home-timeline-java-sdk.java @@ -0,0 +1,130 @@ +package com.twitter.clientlib.auth; + +import java.util.HashSet; +import java.util.Scanner; +import java.util.Set; + +import com.github.scribejava.core.model.OAuth2AccessToken; +import com.github.scribejava.core.pkce.PKCE; +import com.github.scribejava.core.pkce.PKCECodeChallengeMethod; +import com.twitter.clientlib.TwitterCredentialsBearer; +import com.twitter.clientlib.ApiClient; +import com.twitter.clientlib.ApiException; +import com.twitter.clientlib.Configuration; +import com.twitter.clientlib.auth.*; +import com.twitter.clientlib.model.*; +import com.twitter.clientlib.TwitterCredentialsOAuth2; + + +import com.twitter.clientlib.api.TwitterApi; + +import com.twitter.clientlib.api.BookmarksApi; +import java.util.List; +import java.util.Set; +import java.util.Arrays; +import java.util.HashSet; +import java.time.OffsetDateTime; +import org.json.*; + +/** +* This is an example of getting an OAuth2 access token and using it to call an API. +* It's expected to set TWITTER_OAUTH2_CLIENT_ID & TWITTER_OAUTH2_CLIENT_SECRET in TwitterCredentialsOAuth2 +* +* Example steps: +* 1. Getting the App Authorization URL. +* 2. User should click the URL and authorize it. +* 3. After receiving the access token, setting the values into TwitterCredentialsOAuth2. +* 4. Call the API. +*/ + +public class OAuth20GetAccessToken { + + public static void main(String[] args) { + OAuth20GetAccessToken example = new OAuth20GetAccessToken(); + TwitterCredentialsOAuth2 credentials = new TwitterCredentialsOAuth2("REPLACE-WITH-CLIENT-ID", + "REPLACE-WITH-CLIENT-SECRET", + null, + null); + + OAuth2AccessToken accessToken = example.getAccessToken(credentials); + if (accessToken == null) { + return; + } + + // Setting the access & refresh tokens into TwitterCredentialsOAuth2 + credentials.setTwitterOauth2AccessToken(accessToken.getAccessToken()); + credentials.setTwitterOauth2RefreshToken(accessToken.getRefreshToken()); + example.callApi(credentials); + } + + public OAuth2AccessToken getAccessToken(TwitterCredentialsOAuth2 credentials) { + TwitterOAuth20Service service = new TwitterOAuth20Service( + credentials.getTwitterOauth2ClientId(), + credentials.getTwitterOAuth2ClientSecret(), + "https://www.example.com/oauth", + "offline.access tweet.read users.read"); + + OAuth2AccessToken accessToken = null; + try { + final Scanner in = new Scanner(System.in, "UTF-8"); + System.out.println("Fetching the Authorization URL..."); + + final String secretState = "state"; + PKCE pkce = new PKCE(); + pkce.setCodeChallenge("challenge"); + pkce.setCodeChallengeMethod(PKCECodeChallengeMethod.PLAIN); + pkce.setCodeVerifier("challenge"); + String authorizationUrl = service.getAuthorizationUrl(pkce, secretState); + + System.out.println("Go to the Authorization URL and authorize your App:\n" + + authorizationUrl + "\nAfter that paste the authorization code here\n>>"); + final String code = in.nextLine(); + System.out.println("\nTrading the Authorization Code for an Access Token..."); + accessToken = service.getAccessToken(pkce, code); + + System.out.println("Access token: " + accessToken.getAccessToken()); + System.out.println("Refresh token: " + accessToken.getRefreshToken()); + } catch (Exception e) { + System.err.println("Error while getting the access token:\n " + e); + e.printStackTrace(); + } + return accessToken; + } + + public void callApi(TwitterCredentialsOAuth2 credentials) { + TwitterApi apiInstance = new TwitterApi(); + apiInstance.setTwitterCredentials(credentials); + + // Set the params values + String sinceId = "791775337160081409"; // String | The minimum Tweet ID to be included in the result set. This parameter takes precedence over start_time if both are specified. + String untilId = "1346889436626259968"; // String | The maximum Tweet ID to be included in the result set. This parameter takes precedence over end_time if both are specified. + Integer maxResults = 56; // Integer | The maximum number of results + String paginationToken = "paginationToken_example"; // String | This parameter is used to get the next 'page' of results. + OffsetDateTime startTime = OffsetDateTime.parse("2021-02-01T18:40:40.000Z"); // OffsetDateTime | YYYY-MM-DDTHH:mm:ssZ. The earliest UTC timestamp from which the Tweets will be provided. The since_id parameter takes precedence if it is also specified. + OffsetDateTime endTime = OffsetDateTime.parse("2021-02-14T18:40:40.000Z"); // OffsetDateTime | YYYY-MM-DDTHH:mm:ssZ. The latest UTC timestamp to which the Tweets will be provided. The until_id parameter takes precedence if it is also specified. + Set expansions = new HashSet<>(Arrays.asList()); // Set | A comma separated list of fields to expand. + Set tweetFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Tweet fields to display. + Set userFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of User fields to display. + Set mediaFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Media fields to display. + Set placeFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Place fields to display. + Set pollFields = new HashSet<>(Arrays.asList()); // Set | A comma separated list of Poll fields to display. + + try { + //Gets the authorized user ID and parses it into an JSON object + SingleUserLookupResponse userData = apiInstance.users().findMyUser(null, null, null); + String jsonString = userData.getData().toJson(); + JSONObject obj = new JSONObject(jsonString); + String userId = obj.getString("id"); + + //Passes the parsed ID into the userIdTimeline request + GenericTweetsTimelineResponse result = apiInstance.tweets().usersIdTimeline(userId, sinceId, untilId, maxResults, null, paginationToken, startTime, endTime, expansions, tweetFields, userFields, mediaFields, placeFields, pollFields); + System.out.println(result); + } catch (ApiException e) { + System.err.println("Exception when calling UsersApi#usersIdTimeline"); + System.err.println("Status code: " + e.getCode()); + System.err.println("Reason: " + e.getResponseBody()); + System.err.println("Response headers: " + e.getResponseHeaders()); + e.printStackTrace(); + } + } +} diff --git a/java/usage/UsageTweetsDemo.java b/java/usage/UsageTweetsDemo.java new file mode 100644 index 0000000..ecae4b7 --- /dev/null +++ b/java/usage/UsageTweetsDemo.java @@ -0,0 +1,58 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 Usage Tweets endpoint + * */ +public class UsageTweetsDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + String response = getUsageTweets(bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 Usage Tweets endpoint + * */ + private static String getUsageTweets(String bearerToken) throws IOException, URISyntaxException { + String usageTweetsResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/usage/tweets"); + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + usageTweetsResponse = EntityUtils.toString(entity, "UTF-8"); + } + return usageTweetsResponse; + } +} \ No newline at end of file diff --git a/java/users/FollowersLookupDemo.java b/java/users/FollowersLookupDemo.java new file mode 100644 index 0000000..015d8f8 --- /dev/null +++ b/java/users/FollowersLookupDemo.java @@ -0,0 +1,64 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 followers lookup endpoint + * */ +public class FollowersLookupDemo { + + // To set your environment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + final String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + // Replace with user ID below + String response = getFollowers("2244994945", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 followers lookup endpoint by user ID + * */ + private static String getFollowers(String userId, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(String.format("https://api.x.com/2/users/%s/followers", userId)); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("user.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} diff --git a/java/users/FollowingLookupDemo.java b/java/users/FollowingLookupDemo.java new file mode 100644 index 0000000..6b1d453 --- /dev/null +++ b/java/users/FollowingLookupDemo.java @@ -0,0 +1,64 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 following lookup endpoint + * */ +public class FollowingLookupDemo { + + // To set your environment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + final String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + // Replace with user ID below + String response = getFollowing("2244994945", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting your bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 following lookup endpoint + * */ + private static String getFollowing(String userId, String bearerToken) throws IOException, URISyntaxException { + String tweetResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder(String.format("https://api.x.com/2/users/%s/following", userId)); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("user.fields", "created_at")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + tweetResponse = EntityUtils.toString(entity, "UTF-8"); + } + return tweetResponse; + } +} diff --git a/java/users/UsersDemo.java b/java/users/UsersDemo.java new file mode 100644 index 0000000..f9fd8c9 --- /dev/null +++ b/java/users/UsersDemo.java @@ -0,0 +1,66 @@ +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.NameValuePair; +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.CookieSpecs; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.utils.URIBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.util.EntityUtils; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.ArrayList; + +/* + * Sample code to demonstrate the use of the v2 Users endpoint + * */ +public class UsersDemo { + + // To set your enviornment variables in your terminal run the following line: + // export 'BEARER_TOKEN'='' + + public static void main(String args[]) throws IOException, URISyntaxException { + String bearerToken = System.getenv("BEARER_TOKEN"); + if (null != bearerToken) { + //Replace comma separated usernames with usernames of your choice + String response = getUsers("TwitterDev,TwitterEng", bearerToken); + System.out.println(response); + } else { + System.out.println("There was a problem getting you bearer token. Please make sure you set the BEARER_TOKEN environment variable"); + } + } + + /* + * This method calls the v2 Users endpoint with usernames as query parameter + * */ + private static String getUsers(String usernames, String bearerToken) throws IOException, URISyntaxException { + String userResponse = null; + + HttpClient httpClient = HttpClients.custom() + .setDefaultRequestConfig(RequestConfig.custom() + .setCookieSpec(CookieSpecs.STANDARD).build()) + .build(); + + URIBuilder uriBuilder = new URIBuilder("https://api.x.com/2/users/by"); + ArrayList queryParameters; + queryParameters = new ArrayList<>(); + queryParameters.add(new BasicNameValuePair("usernames", usernames)); + queryParameters.add(new BasicNameValuePair("user.fields", "created_at,description,pinned_tweet_id")); + uriBuilder.addParameters(queryParameters); + + HttpGet httpGet = new HttpGet(uriBuilder.build()); + httpGet.setHeader("Authorization", String.format("Bearer %s", bearerToken)); + httpGet.setHeader("Content-Type", "application/json"); + + HttpResponse response = httpClient.execute(httpGet); + HttpEntity entity = response.getEntity(); + if (null != entity) { + userResponse = EntityUtils.toString(entity, "UTF-8"); + } + return userResponse; + } + +} \ No newline at end of file diff --git a/javascript/bookmarks/bookmarks-lookup-js-sdk.js b/javascript/bookmarks/bookmarks-lookup-js-sdk.js new file mode 100644 index 0000000..b6da60c --- /dev/null +++ b/javascript/bookmarks/bookmarks-lookup-js-sdk.js @@ -0,0 +1,92 @@ +const { Client, auth } = require("twitter-api-sdk"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +//Helper function to parse callback +const getQueryStringParams = (query) => { + return query + ? (/^[?#]/.test(query) ? query.slice(1) : query) + .split(/[\?\&]/) + .reduce((params, param) => { + let [key, value] = param.split("="); + params[key] = value + ? decodeURIComponent(value.replace(/\+/g, " ")) + : ""; + return params; + }, {}) + : {}; +}; + +//Helper terminal input function +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CLIENT_ID='YOUR-CLIENT-ID' +// export CLIENET_SECRET='YOUR-CLIENT-SECRET' +const CLIENT_ID = process.env.CLIENT_ID; +const CLIENT_SECRET = process.env.CLIENT_SECRET; + +// Optional parameters for additional payload data +const params = { + expansions: "author_id", + "user.fields": ["username", "created_at"], + "tweet.fields": ["geo", "entities", "context_annotations"], +}; + +(async () => { + const authClient = new auth.OAuth2User({ + client_id: CLIENT_ID, + client_secret: CLIENT_SECRET, + callback: "https://www.example.com/oauth", + scopes: ["tweet.read", "users.read", "bookmark.read"], + }); + + const client = new Client(authClient); + const STATE = "my-state"; + + //Get authorization + const authUrl = authClient.generateAuthURL({ + state: STATE, + code_challenge: "challenge", + }); + + console.log(`Please go here and authorize:`, authUrl); + + //Input users callback url in termnial + const redirectCallback = await input("Paste the redirected callback here: "); + + try { + //Parse callback + const { state, code } = getQueryStringParams(redirectCallback); + if (state !== STATE) { + console.log("State isn't matching"); + } + //Gets access token + await authClient.requestAccessToken(code); + + //Get the user ID + const { + data: { id }, + } = await client.users.findMyUser(); + + //Makes api call + const getBookmark = await client.bookmarks.getUsersIdBookmarks(id, params); + console.dir(getBookmark, { + depth: null, + }); + process.exit(); + } catch (error) { + console.log(error); + } +})(); diff --git a/javascript/bookmarks/create-bookmark-js-sdk.js b/javascript/bookmarks/create-bookmark-js-sdk.js new file mode 100644 index 0000000..8c28b34 --- /dev/null +++ b/javascript/bookmarks/create-bookmark-js-sdk.js @@ -0,0 +1,93 @@ +const { Client, auth } = require("twitter-api-sdk"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +//Helper function to parse callback +const getQueryStringParams = (query) => { + return query + ? (/^[?#]/.test(query) ? query.slice(1) : query) + .split(/[\?\&]/) + .reduce((params, param) => { + let [key, value] = param.split("="); + params[key] = value + ? decodeURIComponent(value.replace(/\+/g, " ")) + : ""; + return params; + }, {}) + : {}; +}; + +//Helper terminal input function +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CLIENT_ID='YOUR-CLIENT-ID' +// export CLIENET_SECRET='YOUR-CLIENT-SECRET' +const CLIENT_ID = process.env.CLIENT_ID; +const CLIENT_SECRET = process.env.CLIENT_SECRET; + +// Include the ID of the Tweet you wish to bookmark +const params = { + tweet_id: "replace-with-tweet-id", +}; + +(async () => { + const authClient = new auth.OAuth2User({ + client_id: CLIENT_ID, + client_secret: CLIENT_SECRET, + callback: "https://www.example.com/oauth", + scopes: ["tweet.read", "users.read", "bookmark.write"], + }); + + const client = new Client(authClient); + const STATE = "my-state"; + + //Get authorization + const authUrl = authClient.generateAuthURL({ + state: STATE, + code_challenge: "challenge", + }); + + console.log(`Please go here and authorize:`, authUrl); + + //Input users callback url in termnial + const redirectCallback = await input("Paste the redirected callback here: "); + + try { + //Parse callback + const { state, code } = getQueryStringParams(redirectCallback); + if (state !== STATE) { + console.log("State isn't matching"); + } + //Gets access token + await authClient.requestAccessToken(code); + + //Get the user ID + const { + data: { id }, + } = await client.users.findMyUser(); + + //Makes api call + const postBookmark = await client.bookmarks.postUsersIdBookmarks( + id, + params + ); + console.dir(postBookmark, { + depth: null, + }); + process.exit(); + } catch (error) { + console.log(error); + } +})(); diff --git a/javascript/bookmarks/delete-bookmark-js-sdk.js b/javascript/bookmarks/delete-bookmark-js-sdk.js new file mode 100644 index 0000000..91a5625 --- /dev/null +++ b/javascript/bookmarks/delete-bookmark-js-sdk.js @@ -0,0 +1,91 @@ +const { Client, auth } = require("twitter-api-sdk"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +//Helper function to parse callback +const getQueryStringParams = (query) => { + return query + ? (/^[?#]/.test(query) ? query.slice(1) : query) + .split(/[\?\&]/) + .reduce((params, param) => { + let [key, value] = param.split("="); + params[key] = value + ? decodeURIComponent(value.replace(/\+/g, " ")) + : ""; + return params; + }, {}) + : {}; +}; + +//Helper terminal input function +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CLIENT_ID='YOUR-CLIENT-ID' +// export CLIENET_SECRET='YOUR-CLIENT-SECRET' +const CLIENT_ID = process.env.CLIENT_ID; +const CLIENT_SECRET = process.env.CLIENT_SECRET; + +// Include the ID of the Tweet you wish to unbookmark +const tweetId = "replace-with-tweet-id"; + +(async () => { + const authClient = new auth.OAuth2User({ + client_id: CLIENT_ID, + client_secret: CLIENT_SECRET, + callback: "https://www.example.com/oauth", + scopes: ["tweet.read", "users.read", "bookmark.write"], + }); + + const client = new Client(authClient); + const STATE = "my-state"; + + //Get authorization + const authUrl = authClient.generateAuthURL({ + state: STATE, + code_challenge: "challenge", + }); + + console.log(`Please go here and authorize:`, authUrl); + + //Input users callback url in termnial + const redirectCallback = await input("Paste the redirected callback here: "); + + try { + //Parse callback + const { state, code } = getQueryStringParams(redirectCallback); + if (state !== STATE) { + console.log("State isn't matching"); + } + //Gets access token + await authClient.requestAccessToken(code); + + //Get the user ID + const { + data: { id }, + } = await client.users.findMyUser(); + + //Makes api call + const deleteBookmark = await client.bookmarks.usersIdBookmarksDelete( + id, + tweetId + ); + console.dir(deleteBookmark, { + depth: null, + }); + process.exit(); + } catch (error) { + console.log(error); + } +})(); diff --git a/javascript/compliance/create_compliance_job.js b/javascript/compliance/create_compliance_job.js new file mode 100644 index 0000000..14e6dee --- /dev/null +++ b/javascript/compliance/create_compliance_job.js @@ -0,0 +1,47 @@ +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = 'https://api.x.com/2/compliance/jobs' + +// For User Compliance Job, replace type value with users instead of tweets +// Also replace the name value with your desired job name +const data = { + "type": "tweets", + "name": 'my_batch_compliance_job' +} + +async function makeRequest() { + + const res = await needle.post(endpointUrl, { + json: data, + headers: { + "User-Agent": "v2BatchComplianceJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + // Make request + const response = await makeRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/compliance/download_compliance_results.js b/javascript/compliance/download_compliance_results.js new file mode 100644 index 0000000..f23a960 --- /dev/null +++ b/javascript/compliance/download_compliance_results.js @@ -0,0 +1,31 @@ +const needle = require('needle'); + +// Replace with your job download_url +downloadUrl = '' + +async function getRequest() { + + const res = await needle('get', downloadUrl, { compressed: true }) + + if (res.body) { + return res.body.toString('utf8'); + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/compliance/get_compliance_job_information_by_id.js b/javascript/compliance/get_compliance_job_information_by_id.js new file mode 100644 index 0000000..18e85a9 --- /dev/null +++ b/javascript/compliance/get_compliance_job_information_by_id.js @@ -0,0 +1,43 @@ +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +// Replace with your job ID +jobId = '' + +const endpointUrl = `https://api.x.com/2/compliance/jobs/${jobId}` + +async function getRequest() { + + const res = await needle('get', endpointUrl, { + headers: { + "User-Agent": "v2BatchComplianceJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/compliance/get_list_of_compliance_jobs.js b/javascript/compliance/get_list_of_compliance_jobs.js new file mode 100644 index 0000000..b52e55e --- /dev/null +++ b/javascript/compliance/get_list_of_compliance_jobs.js @@ -0,0 +1,45 @@ +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = 'https://api.x.com/2/compliance/jobs' + +// For User Compliance job, replace the value for type with users +const params = { + "type": "tweets", +} + +async function getRequest() { + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2BatchComplianceJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/compliance/upload_ids.js b/javascript/compliance/upload_ids.js new file mode 100644 index 0000000..73ccc5d --- /dev/null +++ b/javascript/compliance/upload_ids.js @@ -0,0 +1,40 @@ +const got = require('got'); +const fs = require('fs'); + +// Replace with your job download_url +uploadUrl = '' + +// Replace with your file path that contains the list of Tweet IDs or User IDs, one ID per line +const readStream = fs.createReadStream('/path/to/file'); + +async function getRequest() { + + const res = await got.put(uploadUrl, { + body: readStream, + headers: { + "Content-Type": "text/plain" + } + }) + + if (res.statusCode == 200) { + return res.statusCode; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/List-tweets.js b/javascript/lists/List-tweets.js new file mode 100644 index 0000000..57783fc --- /dev/null +++ b/javascript/lists/List-tweets.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "list-id"; + +const endpointURL = `https://api.x.com/2/lists/${id}/tweets`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the Tweet ID and text are returned + const params = { + "tweet.fields": "lang,author_id", // Edit optional query parameters here + expansions: "author_id", // expansions is used to include the user object + "user.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2ListTweetsLookupJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/Pinned-List.js b/javascript/lists/Pinned-List.js new file mode 100644 index 0000000..d11de05 --- /dev/null +++ b/javascript/lists/Pinned-List.js @@ -0,0 +1,150 @@ +// Pin a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const needle = require("needle"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +const params = { + "list.fields": `owner_id`, // Edit optional query parameters here + expansions: `owner_id`, // expansions is used to include the user object + "user.fields": `created_at,verified`, // Edit optional query parameters here +}; + +const endpointURL = `https://api.x.com/2/users/${id}/pinned_lists`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "GET", + }, + token + ) + ); + + const req = await needle("get", endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2pinListLookupJS", + "content-type": "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/add_member.js b/javascript/lists/add_member.js new file mode 100644 index 0000000..0c5befa --- /dev/null +++ b/javascript/lists/add_member.js @@ -0,0 +1,151 @@ +// Add member to a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-list-id with your own list ID or one of an authenticated user +const id = "your-list-id"; + +// Be sure to replace user-id-to-add with the user id you wish to add. +// You can find a user ID by using the user lookup endpoint +const data = { + user_id: "user-id-to-add", +}; + +const endpointURL = `https://api.x.com/2/lists/${id}/members`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "POST", + }, + token + ) + ); + + const req = await got.post(endpointURL, { + json: data, + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2addMemberJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/create_a_list.js b/javascript/lists/create_a_list.js new file mode 100644 index 0000000..4a60525 --- /dev/null +++ b/javascript/lists/create_a_list.js @@ -0,0 +1,150 @@ +// Create a new list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to add replace name-of-list with the name you wish to call the list. +// description and private keys are optional +const data = { + name: "name-of-list", + description: "description-of-list", + private: false, +}; + +const endpointURL = `https://api.x.com/2/lists`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "POST", + }, + token + ) + ); + + const req = await got.post(endpointURL, { + json: data, + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2createListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/delete_a_list.js b/javascript/lists/delete_a_list.js new file mode 100644 index 0000000..75d55de --- /dev/null +++ b/javascript/lists/delete_a_list.js @@ -0,0 +1,144 @@ +// Delete an existing list the authenticated user owns - using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to add replace the your-list-id with the id of the list you wish to delete. +const target_list_id = "your-list-id"; + +const endpointURL = `https://api.x.com/2/lists/${target_list_id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "DELETE", + }, + token + ) + ); + + const req = await got.delete(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2deleteListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/follow_list.js b/javascript/lists/follow_list.js new file mode 100644 index 0000000..ed0cc4b --- /dev/null +++ b/javascript/lists/follow_list.js @@ -0,0 +1,152 @@ +// Follow a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to add replace list-id-to-follow with the list id you wish to follow. + +const data = { + list_id: "list-id-to-follow", +}; + +const endpointURL = `https://api.x.com/2/users/${id}/followed_lists`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "POST", + }, + token + ) + ); + + const req = await got.post(endpointURL, { + json: data, + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2followListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/list-followers-lookup.js b/javascript/lists/list-followers-lookup.js new file mode 100644 index 0000000..abae1a7 --- /dev/null +++ b/javascript/lists/list-followers-lookup.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "list-id"; + +const endpointURL = `https://api.x.com/2/lists/${id}/followers`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the User ID and name are returned + const params = { + "user.fields": "pinned_tweet_id,created_at", // Edit optional query parameters here + expansions: "pinned_tweet_id", // expansions is used to include the Tweet object + "tweet.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2ListFollowersLookupJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/list-lookup-by-id.js b/javascript/lists/list-lookup-by-id.js new file mode 100644 index 0000000..1a04544 --- /dev/null +++ b/javascript/lists/list-lookup-by-id.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "list-id"; + +const endpointURL = `https://api.x.com/2/lists/${id}`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the List ID and name are returned + const params = { + "list.fields": "owner_id", // Edit optional query parameters here + expansions: "owner_id", // expansions is used to include the user object + "user.fields": "created_at,verified", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2ListLookupJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/list-member-lookup.js b/javascript/lists/list-member-lookup.js new file mode 100644 index 0000000..ebd86a9 --- /dev/null +++ b/javascript/lists/list-member-lookup.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "list-id"; + +const endpointURL = `https://api.x.com/2/lists/${id}/members`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the User ID and name are returned + const params = { + "user.fields": "pinned_tweet_id,created_at", // Edit optional query parameters here + expansions: "pinned_tweet_id", // expansions is used to include the Tweet object + "tweet.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2ListMembersLookupJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/pin_list.js b/javascript/lists/pin_list.js new file mode 100644 index 0000000..a2a2ac6 --- /dev/null +++ b/javascript/lists/pin_list.js @@ -0,0 +1,152 @@ +// Pin a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to add replace list-id-to-pin with the list id you wish to pin. + +const data = { + list_id: "list-id-to-pin", +}; + +const endpointURL = `https://api.x.com/2/users/${id}/pinned_lists`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "POST", + }, + token + ) + ); + + const req = await got.post(endpointURL, { + json: data, + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2pinListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/remove_member.js b/javascript/lists/remove_member.js new file mode 100644 index 0000000..0059a2b --- /dev/null +++ b/javascript/lists/remove_member.js @@ -0,0 +1,149 @@ +// Remove member from a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-list-id with your own list ID or one of an authenticated user +const id = "your-list-id"; + +// Be sure to replace user-id-to-remove with the user id you wish to remove. +// You can find a user ID by using the user lookup endpoint + +const user_id = "user-id-to-remove"; + +const endpointURL = `https://api.x.com/2/lists/${id}/members/${user_id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "DELETE", + }, + token + ) + ); + + const req = await got.delete(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2removeMemberJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/unfollow_list.js b/javascript/lists/unfollow_list.js new file mode 100644 index 0000000..7d47e23 --- /dev/null +++ b/javascript/lists/unfollow_list.js @@ -0,0 +1,149 @@ +// Unfollow a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to replace list-id-to-unfollow with the user id you wish to unfollow. + +const list_id = "list-id-to-unfollow"; + +const endpointURL = `https://api.x.com/2/users/${id}/followed_lists/${list_id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "DELETE", + }, + token + ) + ); + + const req = await got.delete(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2unfollowListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/unpin_list.js b/javascript/lists/unpin_list.js new file mode 100644 index 0000000..1cfdc8c --- /dev/null +++ b/javascript/lists/unpin_list.js @@ -0,0 +1,149 @@ +// Unpin a list using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to replace list-id-to-unpin with the user id you wish to unpin. + +const list_id = "list-id-to-unpin"; + +const endpointURL = `https://api.x.com/2/users/${id}/pinned_lists/${list_id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "DELETE", + }, + token + ) + ); + + const req = await got.delete(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2unpinListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/update_a_list.js b/javascript/lists/update_a_list.js new file mode 100644 index 0000000..7c6d428 --- /dev/null +++ b/javascript/lists/update_a_list.js @@ -0,0 +1,153 @@ +// Update the metadata of an existing list the authenticated user owns - using PIN-based OAuth to authorize the user +// https://developer.twitter.com/en/docs/twitter-api/lists/manage-lists/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to add replace update-name-of-list with the name you wish to call the list. +// name, description and private are all optional +const data = { + name: "update-name-of-list", + description: "update-description-of-list", + private: false, +}; + +// Be sure to add replace the your-list-id with the list id of the list you wish to update. +const target_list_id = "your-list-id"; + +const endpointURL = `https://api.x.com/2/lists/${target_list_id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "PUT", + }, + token + ) + ); + + const req = await got.put(endpointURL, { + json: data, + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2updateListJS", + "content-type": "application/json", + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/user-list-followed.js b/javascript/lists/user-list-followed.js new file mode 100644 index 0000000..7bf4a52 --- /dev/null +++ b/javascript/lists/user-list-followed.js @@ -0,0 +1,48 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "user-id"; + +const endpointURL = `https://api.x.com/2/users/${id}/followed_lists`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the List ID and name are returned + const params = { + "list.fields": "owner_id", // Edit optional query parameters here + expansions: "owner_id", // expansions is used to include the user object + "user.fields": "created_at,verified", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2userListMembershipsJS", + authorization: `Bearer ${token}`, + "x-des-apiservices": "staging1", + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/user-list-memberships.js b/javascript/lists/user-list-memberships.js new file mode 100644 index 0000000..fa196c4 --- /dev/null +++ b/javascript/lists/user-list-memberships.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "user-id"; + +const endpointURL = `https://api.x.com/2/users/${id}/list_memberships`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the List ID and name are returned + const params = { + "list.fields": "owner_id", // Edit optional query parameters here + expansions: "owner_id", // expansions is used to include the user object + "user.fields": "created_at,verified", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2userListMembershipsJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/lists/user-owned-list-lookup.js b/javascript/lists/user-owned-list-lookup.js new file mode 100644 index 0000000..f695cf8 --- /dev/null +++ b/javascript/lists/user-owned-list-lookup.js @@ -0,0 +1,47 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "user-id"; + +const endpointURL = `https://api.x.com/2/users/${id}/owned_lists`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the List ID and name are returned + const params = { + "list.fields": "owner_id", // Edit optional query parameters here + expansions: "owner_id", // expansions is used to include the user object + "user.fields": "created_at,verified", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2ListLookupJS", + authorization: `Bearer ${token}`, + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/block_a_user.js b/javascript/posts/block_a_user.js new file mode 100644 index 0000000..626b027 --- /dev/null +++ b/javascript/posts/block_a_user.js @@ -0,0 +1,150 @@ +// Block a user, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to add replace id-to-block with the user id you wish to block. +// You can find a user ID by using the user lookup endpoint +const data = { + "target_user_id": "id-to-block" +} + +const endpointURL = `https://api.x.com/2/users/${id}/blocking`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'POST' + }, token)); + + const req = await got.post(endpointURL, { + json: data, + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2BlockUserJS", + 'content-type': "application/json", + 'accept': "application/json" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/create_tweet.js b/javascript/posts/create_tweet.js new file mode 100644 index 0000000..eb15cec --- /dev/null +++ b/javascript/posts/create_tweet.js @@ -0,0 +1,144 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to add replace the text of the with the text you wish to Tweet. +// You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. +const data = { + "text": "Hello world!" +}; + +const endpointURL = `https://api.x.com/2/tweets`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'POST' + }, token)); + + const req = await got.post(endpointURL, { + json: data, + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2CreateTweetJS", + 'content-type': "application/json", + 'accept': "application/json" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/delete_tweet.js b/javascript/posts/delete_tweet.js new file mode 100644 index 0000000..ea6bfbd --- /dev/null +++ b/javascript/posts/delete_tweet.js @@ -0,0 +1,142 @@ +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-tweet-id with the id of the Tweet you wish to delete. +const id = "your-tweet-id"; + +const endpointURL = `https://api.x.com/2/tweets/${id}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "DELETE", + }, + token + ) + ); + + const req = await got.delete(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2DeleteTweetJS", + "content-type": "application/json" + accept: "application/json", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/full-archive-search.js b/javascript/posts/full-archive-search.js new file mode 100644 index 0000000..c76d67e --- /dev/null +++ b/javascript/posts/full-archive-search.js @@ -0,0 +1,51 @@ +// Search for public Tweets across the whole Twitter archive +// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/full-archive-search + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = 'https://api.x.com/2/tweets/search/all' + +async function getRequest() { + + // These are the parameters for the API request + // specify Tweet IDs to fetch, and any additional fields that are required + // by default, only the Tweet ID and text are returned + const params = { + 'query': 'from:twitterdev -is:retweet', + 'tweet.fields': 'author_id' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2FullArchiveJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/full_archive_tweet_counts.js b/javascript/posts/full_archive_tweet_counts.js new file mode 100644 index 0000000..8ac536f --- /dev/null +++ b/javascript/posts/full_archive_tweet_counts.js @@ -0,0 +1,51 @@ +// Search for public Tweets across the whole Twitter archive +// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/full-archive-search + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = 'https://api.x.com/2/tweets/counts/all' + +async function getRequest() { + + // Edit query parameters below and specify a search query + // optional params: start_time,end_time,since_id,until_id,next_token,granularity + const params = { + 'query': 'from:twitterdev', + 'granularity': 'day', + 'start_time': '2021-01-01T00:00:00Z' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2FullArchiveTweetCountsJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/get_tweets_with_bearer_token.js b/javascript/posts/get_tweets_with_bearer_token.js new file mode 100644 index 0000000..fcdf694 --- /dev/null +++ b/javascript/posts/get_tweets_with_bearer_token.js @@ -0,0 +1,53 @@ +// Get Tweet objects by ID, using bearer token authentication +// https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/quick-start + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointURL = "https://api.x.com/2/tweets?ids="; + +async function getRequest() { + + // These are the parameters for the API request + // specify Tweet IDs to fetch, and any additional fields that are required + // by default, only the Tweet ID and text are returned + const params = { + "ids": "1278747501642657792,1255542774432063488", // Edit Tweet IDs to look up + "tweet.fields": "lang,author_id", // Edit optional query parameters here + "user.fields": "created_at" // Edit optional query parameters here + } + + // this is the HTTP header that adds bearer token authentication + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2TweetLookupJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/get_tweets_with_user_context.js b/javascript/posts/get_tweets_with_user_context.js new file mode 100644 index 0000000..c769f6f --- /dev/null +++ b/javascript/posts/get_tweets_with_user_context.js @@ -0,0 +1,150 @@ +// Get Tweet objects by ID, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/quick-start + +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// These are the parameters for the API request +// specify Tweet IDs to fetch, and any additional fields that are required +// by default, only the Tweet ID and text are returned +const tweetIDs = '1278747501642657792,1275828087666679809'; // Edit the Tweet IDs to look up +const params = 'tweet.fields=lang,author_id&user.fields=created_at'; // Edit optional query parameters here + +const endpointURL = `https://api.x.com/2/tweets?ids=${tweetIDs}&${params}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; + +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'GET' + }, token)); + + const req = await got(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2TweetLookupJS" + } + }); + + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + + // Get request token + const oAuthRequestToken = await requestToken(); + + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/like_a_tweet.js b/javascript/posts/like_a_tweet.js new file mode 100644 index 0000000..9ff9203 --- /dev/null +++ b/javascript/posts/like_a_tweet.js @@ -0,0 +1,148 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticating user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// You can replace Tweet ID given with the Tweet ID you wish to like. +// You can find a Tweet ID by using the Tweet lookup endpoint +const data = { + "tweet_id": "1354143047324299264" +}; + +const endpointURL = `https://api.x.com/2/users/${id}/likes`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'POST' + }, token)); + + const req = await got.post(endpointURL, { + json: data, + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2LikeTweetJS", + 'content-type': "application/json", + 'accept': "application/json" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/liked_tweets.js b/javascript/posts/liked_tweets.js new file mode 100644 index 0000000..ea65a93 --- /dev/null +++ b/javascript/posts/liked_tweets.js @@ -0,0 +1,46 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; +const id = "your-user-id"; + +const endpointURL = `https://api.x.com/2/users/${id}/liked_tweets`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the Tweet ID and text are returned + const params = { + "tweet.fields": "lang,author_id", // Edit optional query parameters here + "user.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2LikedTweetsJS", + authorization: `Bearer ${token}` + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/liking_users.js b/javascript/posts/liking_users.js new file mode 100644 index 0000000..406025d --- /dev/null +++ b/javascript/posts/liking_users.js @@ -0,0 +1,49 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; + +// You can replace the ID given with the Tweet ID you wish to like. +// You can find an ID by using the Tweet lookup endpoint +const id = "1354143047324299264"; + +const endpointURL = `https://api.x.com/2/tweets/${id}/liking_users`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the Tweet ID and text are returned + const params = { + "tweet.fields": "lang,author_id", // Edit optional query parameters here + "user.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2LikingUsersJS", + authorization: `Bearer ${token}` + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/quote_tweets.js b/javascript/posts/quote_tweets.js new file mode 100644 index 0000000..ccc4230 --- /dev/null +++ b/javascript/posts/quote_tweets.js @@ -0,0 +1,74 @@ +// Get Quote Tweets by Tweet ID +// https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets-lookup/quick-start + +const needle = require('needle'); + +const tweetId = 20; +const url = `https://api.x.com/2/tweets/${tweetId}/quote_tweets`; + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const bearerToken = process.env.BEARER_TOKEN; + +// this is the ID for @TwitterDev +const getQuoteTweets = async () => { + let quoteTweets = []; + let params = { + "max_results": 100, + "tweet.fields": "created_at" + } + + const options = { + headers: { + "User-Agent": "v2QuoteTweetsJS", + "authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + console.log("Retrieving quote Tweets..."); + while (hasNextPage) { + let resp = await getPage(params, options, nextToken); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + if (resp.data) { + quoteTweets.push.apply(quoteTweets, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + console.dir(quoteTweets, { + depth: null + }); + + console.log(`Got ${quoteTweets.length} quote Tweets for Tweet ID ${tweetId}!`); + +} + +const getPage = async (params, options, nextToken) => { + if (nextToken) { + params.pagination_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} + +getQuoteTweets(); diff --git a/javascript/posts/recent_search.js b/javascript/posts/recent_search.js new file mode 100644 index 0000000..1d82ed4 --- /dev/null +++ b/javascript/posts/recent_search.js @@ -0,0 +1,51 @@ +// Search for Tweets within the past seven days +// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = "https://api.x.com/2/tweets/search/recent"; + +async function getRequest() { + + // Edit query parameters below + // specify a search query, and any additional fields that are required + // by default, only the Tweet ID and text fields are returned + const params = { + 'query': 'from:twitterdev -is:retweet', + 'tweet.fields': 'author_id' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2RecentSearchJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/recent_tweet_counts.js b/javascript/posts/recent_tweet_counts.js new file mode 100644 index 0000000..73b981f --- /dev/null +++ b/javascript/posts/recent_tweet_counts.js @@ -0,0 +1,50 @@ +// Search for Tweets within the past seven days +// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = "https://api.x.com/2/tweets/counts/recent"; + +async function getRequest() { + + // Edit query parameters below and specify a search query + // optional params: start_time,end_time,since_id,until_id,next_token,granularity + const params = { + 'query': 'from:twitterdev', + 'granularity': 'day' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2RecentTweetCountsJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/retweet_a_tweet.js b/javascript/posts/retweet_a_tweet.js new file mode 100644 index 0000000..875b67b --- /dev/null +++ b/javascript/posts/retweet_a_tweet.js @@ -0,0 +1,148 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// You can replace the given Tweet ID with your the Tweet ID you want to Retweet +// You can find a Tweet ID by using the Tweet lookup endpoint +const data = { + "tweet_id": "1412865600439738368" +} + +const endpointURL = `https://api.x.com/2/users/${id}/retweets`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'POST' + }, token)); + + const req = await got.post(endpointURL, { + json: data, + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "vsRetweetTweetJS", + 'content-type': "application/json", + 'accept': "application/json" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/retweeted_by.js b/javascript/posts/retweeted_by.js new file mode 100644 index 0000000..3d25df8 --- /dev/null +++ b/javascript/posts/retweeted_by.js @@ -0,0 +1,49 @@ +const needle = require("needle"); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' + +const token = process.env.BEARER_TOKEN; + +// You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for +// You can find an ID by using the Tweet lookup endpoint +const id = "1354143047324299264"; + +const endpointURL = `https://api.x.com/2/tweets/${id}/retweeted_by`; + +async function getRequest() { + // These are the parameters for the API request + // by default, only the Tweet ID and text are returned + const params = { + "tweet.fields": "lang,author_id", // Edit optional query parameters here + "user.fields": "created_at", // Edit optional query parameters here + }; + + // this is the HTTP header that adds bearer token authentication + const res = await needle("get", endpointURL, params, { + headers: { + "User-Agent": "v2RetweetedByUsersJS", + authorization: `Bearer ${token}` + }, + }); + + if (res.body) { + return res.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/unblock_a_user.js b/javascript/posts/unblock_a_user.js new file mode 100644 index 0000000..d8d5081 --- /dev/null +++ b/javascript/posts/unblock_a_user.js @@ -0,0 +1,149 @@ +// Unblock a user, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const source_user_id = "your-user-id"; + + +// Be sure to add replace the id-to-unblock with the user id of the you wish to unblock. +// You can find a user ID by using the user lookup endpoint +const target_user_id = "id-to-unblock" + +const endpointURL = `https://api.x.com/2/users/${source_user_id}/blocking/${target_user_id}`; + + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'DELETE' + }, token)); + + const req = await got.post(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UnblockUserJS" + } + }); + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); + + +// Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/javascript/posts/undo_a_retweet.js b/javascript/posts/undo_a_retweet.js new file mode 100644 index 0000000..1d0029f --- /dev/null +++ b/javascript/posts/undo_a_retweet.js @@ -0,0 +1,145 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticating user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + + +// You can replace the given Tweet ID with your the Tweet ID you want to Retweet +// You can find a Tweet ID by using the Tweet lookup endpoint +const source_tweet_id = "1354143047324299264"; + +const endpointURL = `https://api.x.com/2/users/${id}/retweets/${source_tweet_id}`; + + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'DELETE' + }, token)); + + const req = await got.delete(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UndoRetweetTweetJS" + } + }); + + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/posts/unlike_a_tweet.js b/javascript/posts/unlike_a_tweet.js new file mode 100644 index 0000000..f7c5905 --- /dev/null +++ b/javascript/posts/unlike_a_tweet.js @@ -0,0 +1,145 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}); + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticating user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + + +// You can replace Tweet ID given with the Tweet ID you wish to like. +// You can find a Tweet ID by using the Tweet lookup endpoint +const tweet_id = "1354143047324299264"; + +const endpointURL = `https://api.x.com/2/users/${id}/likes/${tweet_id}`; + + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'DELETE' + }, token)); + + const req = await got.delete(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UnlikeTweetJS" + } + }); + + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/spaces/search_spaces.js b/javascript/spaces/search_spaces.js new file mode 100644 index 0000000..eb58ed3 --- /dev/null +++ b/javascript/spaces/search_spaces.js @@ -0,0 +1,51 @@ +// Lookup Spaces by ID +// https://developer.twitter.com/en/docs/twitter-api/spaces/lookup + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = `https://api.x.com/2/spaces/search`; + +async function getRequest() { + + // Edit query parameters below and specify a search query + // optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at + const params = { + 'query': 'NBA', // Replace the value with your search term + 'space.fields': 'title,created_at', + 'expansions': 'creator_id' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2SpacesSearchJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/spaces/spaces_lookup.js b/javascript/spaces/spaces_lookup.js new file mode 100644 index 0000000..73b981f --- /dev/null +++ b/javascript/spaces/spaces_lookup.js @@ -0,0 +1,50 @@ +// Search for Tweets within the past seven days +// https://developer.twitter.com/en/docs/twitter-api/tweets/search/quick-start/recent-search + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointUrl = "https://api.x.com/2/tweets/counts/recent"; + +async function getRequest() { + + // Edit query parameters below and specify a search query + // optional params: start_time,end_time,since_id,until_id,next_token,granularity + const params = { + 'query': 'from:twitterdev', + 'granularity': 'day' + } + + const res = await needle('get', endpointUrl, params, { + headers: { + "User-Agent": "v2RecentTweetCountsJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/streams/filtered_stream.js b/javascript/streams/filtered_stream.js index 5fd747a..3926e98 100644 --- a/javascript/streams/filtered_stream.js +++ b/javascript/streams/filtered_stream.js @@ -1,88 +1,103 @@ -/** - * Filtered Stream - X API v2 - * - * Endpoint: GET https://api.x.com/2/tweets/search/stream - * Docs: https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream - * - * Authentication: Bearer Token (App-only) - * Required env vars: BEARER_TOKEN - * - * This example demonstrates: - * 1. Getting existing rules - * 2. Deleting all existing rules - * 3. Setting new rules - * 4. Connecting to the stream - */ +// Open a realtime stream of Tweets, filtered according to rules +// https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/quick-start const needle = require('needle'); +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' const token = process.env.BEARER_TOKEN; + const rulesURL = 'https://api.x.com/2/tweets/search/stream/rules'; const streamURL = 'https://api.x.com/2/tweets/search/stream'; -// Adjust rules as needed -const rules = [ - { 'value': 'dog has:images', 'tag': 'dog pictures' }, - { 'value': 'cat has:images -grumpy', 'tag': 'cat pictures' }, +// this sets up two rules - the value is the search terms to match on, and the tag is an identifier that +// will be applied to the Tweets return to show which rule they matched +// with a standard project with Basic Access, you can add up to 25 concurrent rules to your stream, and +// each rule can be up to 512 characters long + +// Edit rules as desired below +const rules = [{ + 'value': 'dog has:images -is:retweet', + 'tag': 'dog pictures' + }, + { + 'value': 'cat has:images -grumpy', + 'tag': 'cat pictures' + }, ]; async function getAllRules() { + const response = await needle('get', rulesURL, { headers: { "authorization": `Bearer ${token}` } - }); + }) if (response.statusCode !== 200) { - throw new Error(`Error getting rules: ${response.body}`); + console.log("Error:", response.statusMessage, response.statusCode) + throw new Error(response.body); } - return response.body; + return (response.body); } async function deleteAllRules(rules) { + if (!Array.isArray(rules.data)) { return null; } const ids = rules.data.map(rule => rule.id); - const data = { "delete": { "ids": ids } }; + + const data = { + "delete": { + "ids": ids + } + } const response = await needle('post', rulesURL, data, { headers: { "content-type": "application/json", "authorization": `Bearer ${token}` } - }); + }) if (response.statusCode !== 200) { - throw new Error(`Error deleting rules: ${response.body}`); + throw new Error(response.body); } - return response.body; + return (response.body); + } async function setRules() { - const data = { "add": rules }; + + const data = { + "add": rules + } const response = await needle('post', rulesURL, data, { headers: { "content-type": "application/json", "authorization": `Bearer ${token}` } - }); + }) if (response.statusCode !== 201) { - throw new Error(`Error setting rules: ${response.body}`); + throw new Error(response.body); } - return response.body; + return (response.body); + } -function streamConnect() { +function streamConnect(retryAttempt) { + const stream = needle.get(streamURL, { headers: { - "User-Agent": "v2FilteredStreamJS", + "User-Agent": "v2FilterStreamJS", "Authorization": `Bearer ${token}` }, timeout: 20000 @@ -92,39 +107,54 @@ function streamConnect() { try { const json = JSON.parse(data); console.log(json); + // A successful connection resets retry count. + retryAttempt = 0; } catch (e) { - // Keep alive signal received + if (data.detail === "This stream is currently at the maximum allowed connection limit.") { + console.log(data.detail) + process.exit(1) + } else { + // Keep alive signal received. Do nothing. + } } - }); - - stream.on('error', error => { - if (error.code === 'ETIMEDOUT') { - stream.emit('timeout'); + }).on('err', error => { + if (error.code !== 'ECONNRESET') { + console.log(error.code); + process.exit(1); + } else { + // This reconnection logic will attempt to reconnect when a disconnection is detected. + // To avoid rate limits, this logic implements exponential backoff, so the wait time + // will increase if the client cannot reconnect to the stream. + setTimeout(() => { + console.warn("A connection error occurred. Reconnecting...") + streamConnect(++retryAttempt); + }, 2 ** retryAttempt) } }); return stream; + } + (async () => { + let currentRules; + try { - // Get all stream rules - let currentRules = await getAllRules(); - console.log("Current rules:", currentRules); + // Gets the complete list of rules currently applied to the stream + currentRules = await getAllRules(); - // Delete all stream rules + // Delete all rules. Comment the line below if you want to keep your existing rules. await deleteAllRules(currentRules); - console.log("Deleted existing rules"); - // Set new rules + // Add rules to the stream. Comment the line below if you don't want to add new rules. await setRules(); - console.log("Set new rules"); - // Connect to the stream - console.log("Connecting to stream..."); - streamConnect(); } catch (e) { console.error(e); - process.exit(-1); + process.exit(1); } + + // Listen to the stream. + streamConnect(0); })(); diff --git a/javascript/streams/sampled_stream.js b/javascript/streams/sampled_stream.js new file mode 100644 index 0000000..533f747 --- /dev/null +++ b/javascript/streams/sampled_stream.js @@ -0,0 +1,60 @@ +// Open a live stream of roughly 1% random sample of publicly available Tweets +// https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/quick-start + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const streamURL = 'https://api.x.com/2/tweets/sample/stream'; + +function streamConnect(retryAttempt) { + + const stream = needle.get(streamURL, { + headers: { + "User-Agent": "v2SampleStreamJS", + "Authorization": `Bearer ${token}` + }, + timeout: 20000 + }); + + stream.on('data', data => { + try { + const json = JSON.parse(data); + console.log(json); + // A successful connection resets retry count. + retryAttempt = 0; + } catch (e) { + // Catches error in case of 401 unauthorized error status. + if (data.status === 401) { + console.log(data); + process.exit(1); + } else if (data.detail === "This stream is currently at the maximum allowed connection limit.") { + console.log(data.detail) + process.exit(1) + } else { + // Keep alive signal received. Do nothing. + } + } + }).on('err', error => { + if (error.code !== 'ECONNRESET') { + console.log(error.code); + process.exit(1); + } else { + // This reconnection logic will attempt to reconnect when a disconnection is detected. + // To avoid rate limits, this logic implements exponential backoff, so the wait time + // will increase if the client cannot reconnect to the stream. + setTimeout(() => { + console.warn("A connection error occurred. Reconnecting...") + streamConnect(++retryAttempt); + }, 2 ** retryAttempt); + } + }); + return stream; +} + +(async () => { + streamConnect(0) +})(); diff --git a/javascript/timelines/reverse-chron-home-timeline-js-sdk.js b/javascript/timelines/reverse-chron-home-timeline-js-sdk.js new file mode 100644 index 0000000..b0b4cab --- /dev/null +++ b/javascript/timelines/reverse-chron-home-timeline-js-sdk.js @@ -0,0 +1,92 @@ +const { Client, auth } = require("twitter-api-sdk"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +//Helper function to parse callback +const getQueryStringParams = (query) => { + return query + ? (/^[?#]/.test(query) ? query.slice(1) : query) + .split(/[\?\&]/) + .reduce((params, param) => { + let [key, value] = param.split("="); + params[key] = value + ? decodeURIComponent(value.replace(/\+/g, " ")) + : ""; + return params; + }, {}) + : {}; +}; + +//Helper terminal input function +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CLIENT_ID='YOUR-CLIENT-ID' +// export CLIENET_SECRET='YOUR-CLIENT-SECRET' +const CLIENT_ID = process.env.CLIENT_ID; +const CLIENT_SECRET = process.env.CLIENT_SECRET; + +// Optional parameters for additional payload data +const params = { + expansions: "author_id", + "user.fields": ["username", "created_at"], + "tweet.fields": ["geo", "entities", "context_annotations"], +}; + +(async () => { + const authClient = new auth.OAuth2User({ + client_id: CLIENT_ID, + client_secret: CLIENT_SECRET, + callback: "https://www.example.com/oauth", + scopes: ["tweet.read", "users.read"], + }); + + const client = new Client(authClient); + const STATE = "my-state"; + + //Get authorization + const authUrl = authClient.generateAuthURL({ + state: STATE, + code_challenge: "challenge", + }); + + console.log(`Please go here and authorize:`, authUrl); + + //Input users callback url in termnial + const redirectCallback = await input("Paste the redirected callback here: "); + + try { + //Parse callback + const { state, code } = getQueryStringParams(redirectCallback); + if (state !== STATE) { + console.log("State isn't matching"); + } + //Gets access token + await authClient.requestAccessToken(code); + + //Get the user ID + const { + data: { id }, + } = await client.users.findMyUser(); + + //Makes api call + const getUsersTimeline = await client.tweets.usersIdTimeline(id, params); + console.dir(getUsersTimeline, { + depth: null, + }); + process.exit(); + } catch (error) { + console.log(error); + } +})(); diff --git a/javascript/timelines/reverse-chron-home-timeline.js b/javascript/timelines/reverse-chron-home-timeline.js new file mode 100644 index 0000000..51d4dbd --- /dev/null +++ b/javascript/timelines/reverse-chron-home-timeline.js @@ -0,0 +1,142 @@ +// Retrieve accounts muted by authenticated user +// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; +const endpointURL = `https://api.x.com/2/users/${id}/timelines/reverse_chronological`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "GET", + }, + token + ) + ); + + const req = await got.get(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2ReverseChronHomeTimelinesJS", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/timelines/user_mentions.js b/javascript/timelines/user_mentions.js new file mode 100644 index 0000000..98a4fd7 --- /dev/null +++ b/javascript/timelines/user_mentions.js @@ -0,0 +1,74 @@ +// Get User mentions timeline by user ID +// https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/quick-start + +const needle = require('needle'); + +const userId = 2244994945; +const url = `https://api.x.com/2/users/${userId}/mentions`; + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const bearerToken = process.env.BEARER_TOKEN; + +// this is the ID for @TwitterDev +const getUserMentions = async () => { + let userMentions = []; + let params = { + "max_results": 100, + "tweet.fields": "created_at" + } + + const options = { + headers: { + "User-Agent": "v2UserMentionssJS", + "authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + console.log("Retrieving mentions..."); + while (hasNextPage) { + let resp = await getPage(params, options, nextToken); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + if (resp.data) { + userMentions.push.apply(userMentions, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + console.dir(userMentions, { + depth: null + }); + + console.log(`Got ${userMentions.length} mentions for user ID ${userId}!`); + +} + +const getPage = async (params, options, nextToken) => { + if (nextToken) { + params.pagination_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} + +getUserMentions(); diff --git a/javascript/timelines/user_tweets.js b/javascript/timelines/user_tweets.js new file mode 100644 index 0000000..2576822 --- /dev/null +++ b/javascript/timelines/user_tweets.js @@ -0,0 +1,79 @@ +// Get User Tweet timeline by user ID +// https://developer.twitter.com/en/docs/twitter-api/tweets/timelines/quick-start + +const needle = require('needle'); + +// this is the ID for @TwitterDev +const userId = "2244994945"; +const url = `https://api.x.com/2/users/${userId}/tweets`; + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const bearerToken = process.env.BEARER_TOKEN; + +const getUserTweets = async () => { + let userTweets = []; + + // we request the author_id expansion so that we can print out the user name later + let params = { + "max_results": 100, + "tweet.fields": "created_at", + "expansions": "author_id" + } + + const options = { + headers: { + "User-Agent": "v2UserTweetsJS", + "authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + let userName; + console.log("Retrieving Tweets..."); + + while (hasNextPage) { + let resp = await getPage(params, options, nextToken); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + userName = resp.includes.users[0].username; + if (resp.data) { + userTweets.push.apply(userTweets, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + console.dir(userTweets, { + depth: null + }); + console.log(`Got ${userTweets.length} Tweets from ${userName} (user ID ${userId})!`); + +} + +const getPage = async (params, options, nextToken) => { + if (nextToken) { + params.pagination_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} + +getUserTweets(); diff --git a/javascript/usage/get_usage_tweets.js b/javascript/usage/get_usage_tweets.js new file mode 100644 index 0000000..31ec211 --- /dev/null +++ b/javascript/usage/get_usage_tweets.js @@ -0,0 +1,44 @@ +// Get Tweets Usage +// https://developer.twitter.com/en/docs/twitter-api/usage/tweets + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointURL = "https://api.x.com/2/usage/tweets"; + +async function getRequest() { + + // this is the HTTP header that adds bearer token authentication + const res = await needle('get', endpointURL, { + headers: { + "User-Agent": "v2UsageTweetsJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/followers_lookup.js b/javascript/users/followers_lookup.js new file mode 100644 index 0000000..cf93eb1 --- /dev/null +++ b/javascript/users/followers_lookup.js @@ -0,0 +1,67 @@ +// Fetch the followers of a user account, by ID +// https://developer.twitter.com/en/docs/twitter-api/users/follows/quick-start + +const needle = require('needle'); + +// this is the ID for @TwitterDev +const userId = 2244994945; +const url = `https://api.x.com/2/users/${userId}/followers`; +const bearerToken = process.env.BEARER_TOKEN; + +const getFollowers = async () => { + let users = []; + let params = { + "max_results": 1000, + "user.fields": "created_at" + } + + const options = { + headers: { + "User-Agent": "v2FollowersJS", + "authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + console.log("Retrieving followers..."); + while (hasNextPage) { + let resp = await getPage(params, options, nextToken); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + if (resp.data) { + users.push.apply(users, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + console.log(users); + console.log(`Got ${users.length} users.`); + +} + +const getPage = async (params, options, nextToken) => { + if (nextToken) { + params.pagination_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} + +getFollowers(); diff --git a/javascript/users/following_lookup.js b/javascript/users/following_lookup.js new file mode 100644 index 0000000..f5c76db --- /dev/null +++ b/javascript/users/following_lookup.js @@ -0,0 +1,67 @@ +// Fetch the users being followed by a specific account, by ID +// https://developer.twitter.com/en/docs/twitter-api/users/follows/quick-start + +const needle = require('needle'); + +// this is the ID for @TwitterDev +const userId = 2244994945; +const url = `https://api.x.com/2/users/${userId}/following`; +const bearerToken = process.env.BEARER_TOKEN; + +const getFollowing = async () => { + let users = []; + let params = { + "max_results": 1000, + "user.fields": "created_at" + } + + const options = { + headers: { + "User-Agent": "v2FollowingJS", + "Authorization": `Bearer ${bearerToken}` + } + } + + let hasNextPage = true; + let nextToken = null; + console.log("Retrieving users this user is following..."); + while (hasNextPage) { + let resp = await getPage(params, options, nextToken); + if (resp && resp.meta && resp.meta.result_count && resp.meta.result_count > 0) { + if (resp.data) { + users.push.apply(users, resp.data); + } + if (resp.meta.next_token) { + nextToken = resp.meta.next_token; + } else { + hasNextPage = false; + } + } else { + hasNextPage = false; + } + } + + console.log(users); + console.log(`Got ${users.length} users.`); + +} + +const getPage = async (params, options, nextToken) => { + if (nextToken) { + params.pagination_token = nextToken; + } + + try { + const resp = await needle('get', url, params, options); + + if (resp.statusCode != 200) { + console.log(`${resp.statusCode} ${resp.statusMessage}:\n${resp.body}`); + return; + } + return resp.body; + } catch (err) { + throw new Error(`Request failed: ${err}`); + } +} + +getFollowing(); diff --git a/javascript/users/get_users_me_with_user_context.js b/javascript/users/get_users_me_with_user_context.js new file mode 100644 index 0000000..5166717 --- /dev/null +++ b/javascript/users/get_users_me_with_user_context.js @@ -0,0 +1,146 @@ +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// These are the parameters for the API request +// specify Tweet IDs to fetch, and any additional fields that are required +// by default, only the Tweet ID and text are returned +const params = 'user.fields=created_at,description&expansions=pinned_tweet_id' // Edit optional query parameters here + +const endpointURL = `https://api.x.com/2/users/me?{params}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; + +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'GET' + }, token)); + + const req = await got(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UserLookupJS" + } + }); + + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + + // Get request token + const oAuthRequestToken = await requestToken(); + + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/get_users_with_bearer_token.js b/javascript/users/get_users_with_bearer_token.js new file mode 100644 index 0000000..56c4414 --- /dev/null +++ b/javascript/users/get_users_with_bearer_token.js @@ -0,0 +1,53 @@ +// Get User objects by username, using bearer token authentication +// https://developer.twitter.com/en/docs/twitter-api/users/lookup/quick-start + +const needle = require('needle'); + +// The code below sets the bearer token from your environment variables +// To set environment variables on macOS or Linux, run the export command below from the terminal: +// export BEARER_TOKEN='YOUR-TOKEN' +const token = process.env.BEARER_TOKEN; + +const endpointURL = "https://api.x.com/2/users/by?usernames=" + +async function getRequest() { + + // These are the parameters for the API request + // specify User names to fetch, and any additional fields that are required + // by default, only the User ID, name and user name are returned + const params = { + usernames: "TwitterDev,TwitterAPI", // Edit usernames to look up + "user.fields": "created_at,description", // Edit optional query parameters here + "expansions": "pinned_tweet_id" + } + + // this is the HTTP header that adds bearer token authentication + const res = await needle('get', endpointURL, params, { + headers: { + "User-Agent": "v2UserLookupJS", + "authorization": `Bearer ${token}` + } + }) + + if (res.body) { + return res.body; + } else { + throw new Error('Unsuccessful request') + } +} + +(async () => { + + try { + // Make request + const response = await getRequest(); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/get_users_with_user_context.js b/javascript/users/get_users_with_user_context.js new file mode 100644 index 0000000..4cceedb --- /dev/null +++ b/javascript/users/get_users_with_user_context.js @@ -0,0 +1,150 @@ +// Get User objects by username, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/users/lookup/quick-start + +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// These are the parameters for the API request +// specify Tweet IDs to fetch, and any additional fields that are required +// by default, only the Tweet ID and text are returned +const usernames = 'TwitterDev,TwitterAPI' // Edit usernames to look up +const params = 'user.fields=created_at,description&expansions=pinned_tweet_id' // Edit optional query parameters here + +const endpointURL = `https://api.x.com/2/users/by?usernames=${usernames}&${params}`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; + +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'GET' + }, token)); + + const req = await got(endpointURL, { + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UserLookupJS" + } + }); + + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + +(async () => { + try { + + // Get request token + const oAuthRequestToken = await requestToken(); + + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/lookup_blocks.js b/javascript/users/lookup_blocks.js new file mode 100644 index 0000000..a9ff459 --- /dev/null +++ b/javascript/users/lookup_blocks.js @@ -0,0 +1,140 @@ +// Block a user, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/users/blocks/quick-start +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; +const endpointURL = `https://api.x.com/2/users/${id}/blocking`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'GET' + }, token)); + + const req = await got.get(endpointURL, { + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2BlocksLookupJS" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/lookup_mutes.js b/javascript/users/lookup_mutes.js new file mode 100644 index 0000000..d8c9d39 --- /dev/null +++ b/javascript/users/lookup_mutes.js @@ -0,0 +1,142 @@ +// Retrieve accounts muted by authenticated user +// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start +const got = require("got"); +const crypto = require("crypto"); +const OAuth = require("oauth-1.0a"); +const qs = require("querystring"); + +const readline = require("readline").createInterface({ + input: process.stdin, + output: process.stdout, +}); + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; +const endpointURL = `https://api.x.com/2/users/${id}/muting`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = + "https://api.x.com/oauth/request_token?oauth_callback=oob"; +const authorizeURL = new URL("https://api.x.com/oauth/authorize"); +const accessTokenURL = "https://api.x.com/oauth/access_token"; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret, + }, + signature_method: "HMAC-SHA1", + hash_function: (baseString, key) => + crypto.createHmac("sha1", key).update(baseString).digest("base64"), +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: requestTokenURL, + method: "POST", + }) + ); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function accessToken({ oauth_token, oauth_token_secret }, verifier) { + const authHeader = oauth.toHeader( + oauth.authorize({ + url: accessTokenURL, + method: "POST", + }) + ); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}`; + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"], + }, + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error("Cannot get an OAuth request token"); + } +} + +async function getRequest({ oauth_token, oauth_token_secret }) { + const token = { + key: oauth_token, + secret: oauth_token_secret, + }; + + const authHeader = oauth.toHeader( + oauth.authorize( + { + url: endpointURL, + method: "GET", + }, + token + ) + ); + + const req = await got.get(endpointURL, { + responseType: "json", + headers: { + Authorization: authHeader["Authorization"], + "user-agent": "v2MutesLookupJS", + }, + }); + if (req.body) { + return req.body; + } else { + throw new Error("Unsuccessful request"); + } +} + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append( + "oauth_token", + oAuthRequestToken.oauth_token + ); + console.log("Please go here and authorize:", authorizeURL.href); + const pin = await input("Paste the PIN here: "); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null, + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/mute_a_user.js b/javascript/users/mute_a_user.js new file mode 100644 index 0000000..73d12f2 --- /dev/null +++ b/javascript/users/mute_a_user.js @@ -0,0 +1,150 @@ +// mute a user, using user authentication +// https://developer.twitter.com/en/docs/twitter-api/users/mutes/quick-start +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const id = "your-user-id"; + +// Be sure to add replace id-to-mute with the user id you wish to mute. +// You can find a user ID by using the user lookup endpoint +const data = { + "target_user_id": "id-to-mute" +} + +const endpointURL = `https://api.x.com/2/users/${id}/muting`; + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + headers: { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'POST' + }, token)); + + const req = await got.post(endpointURL, { + json: data, + responseType: 'json', + headers: { + Authorization: authHeader["Authorization"], + 'user-agent': "v2muteUserJS", + 'content-type': "application/json", + 'accept': "application/json" + } + }); + if (req.body) { + return req.body; + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/javascript/users/unmute_a_user.js b/javascript/users/unmute_a_user.js new file mode 100644 index 0000000..ddd421c --- /dev/null +++ b/javascript/users/unmute_a_user.js @@ -0,0 +1,145 @@ +// Unmute a user, using user authentication +const got = require('got'); +const crypto = require('crypto'); +const OAuth = require('oauth-1.0a'); +const qs = require('querystring'); + +const readline = require('readline').createInterface({ + input: process.stdin, + output: process.stdout +}) + + +// The code below sets the consumer key and consumer secret from your environment variables +// To set environment variables on macOS or Linux, run the export commands below from the terminal: +// export CONSUMER_KEY='YOUR-KEY' +// export CONSUMER_SECRET='YOUR-SECRET' +const consumer_key = process.env.CONSUMER_KEY; +const consumer_secret = process.env.CONSUMER_SECRET; + + +// Be sure to replace your-user-id with your own user ID or one of an authenticated user +// You can find a user ID by using the user lookup endpoint +const source_user_id = "your-user-id"; + + +// Be sure to add replace the id-to-unmute with the user id of the you wish to unmute. +// You can find a user ID by using the user lookup endpoint +const target_user_id = "id-to-unmute" + +const endpointURL = `https://api.x.com/2/users/${source_user_id}/muting/${target_user_id}`; + + +// this example uses PIN-based OAuth to authorize the user +const requestTokenURL = 'https://api.x.com/oauth/request_token?oauth_callback=oob'; +const authorizeURL = new URL('https://api.x.com/oauth/authorize'); +const accessTokenURL = 'https://api.x.com/oauth/access_token'; +const oauth = OAuth({ + consumer: { + key: consumer_key, + secret: consumer_secret + }, + signature_method: 'HMAC-SHA1', + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64') +}); + +async function input(prompt) { + return new Promise(async (resolve, reject) => { + readline.question(prompt, (out) => { + readline.close(); + resolve(out); + }); + }); +} + +async function requestToken() { + const authHeader = oauth.toHeader(oauth.authorize({ + url: requestTokenURL, + method: 'POST' + })); + + const req = await got.post(requestTokenURL, { + : { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function accessToken({ + oauth_token, + oauth_token_secret +}, verifier) { + const authHeader = oauth.toHeader(oauth.authorize({ + url: accessTokenURL, + method: 'POST' + })); + const path = `https://api.x.com/oauth/access_token?oauth_verifier=${verifier}&oauth_token=${oauth_token}` + const req = await got.post(path, { + : { + Authorization: authHeader["Authorization"] + } + }); + if (req.body) { + return qs.parse(req.body); + } else { + throw new Error('Cannot get an OAuth request token'); + } +} + + +async function getRequest({ + oauth_token, + oauth_token_secret +}) { + + const token = { + key: oauth_token, + secret: oauth_token_secret + }; + + const authHeader = oauth.toHeader(oauth.authorize({ + url: endpointURL, + method: 'DELETE' + }, token)); + + const req = await got.post(endpointURL, { + : { + Authorization: authHeader["Authorization"], + 'user-agent': "v2UnmuteUserJS" + } + }); + if (req.body) { + return JSON.parse(req.body); + } else { + throw new Error('Unsuccessful request'); + } +} + + +(async () => { + try { + // Get request token + const oAuthRequestToken = await requestToken(); + // Get authorization + authorizeURL.searchParams.append('oauth_token', oAuthRequestToken.oauth_token); + console.log('Please go here and authorize:', authorizeURL.href); + const pin = await input('Paste the PIN here: '); + // Get the access token + const oAuthAccessToken = await accessToken(oAuthRequestToken, pin.trim()); + // Make the request + const response = await getRequest(oAuthAccessToken); + console.dir(response, { + depth: null + }); + } catch (e) { + console.log(e); + process.exit(-1); + } + process.exit(); +})(); diff --git a/python/README.md b/python/README.md index 7048b2c..0f21f15 100644 --- a/python/README.md +++ b/python/README.md @@ -1,139 +1,150 @@ # X API v2 - Python Examples -Working Python code samples for the X (formerly Twitter) API v2. +Working Python examples for the X API v2. ## Setup -### 1. Install Python 3.7+ - -```bash -python3 --version -``` - -### 2. Create a virtual environment (recommended) - ```bash -python3 -m venv venv -source venv/bin/activate # On Windows: venv\Scripts\activate +pip install requests requests-oauthlib ``` -### 3. Install dependencies +## Environment Variables -```bash -pip install -r requirements.txt -``` - -### 4. Set environment variables - -For **Bearer Token** authentication (app-only): ```bash export BEARER_TOKEN='your_bearer_token' -``` - -For **OAuth 1.0a** authentication (user context): -```bash export CONSUMER_KEY='your_consumer_key' export CONSUMER_SECRET='your_consumer_secret' ``` -## Examples by Category - -### Posts (Tweets) -| File | Description | Auth | -|------|-------------|------| -| `posts/create_post.py` | Create a new post | OAuth 1.0a | -| `posts/delete_post.py` | Delete a post | OAuth 1.0a | -| `posts/lookup.py` | Look up posts by ID | Bearer | -| `posts/search_recent.py` | Search recent posts (7 days) | Bearer | -| `posts/search_full_archive.py` | Search all posts (Academic) | Bearer | -| `posts/counts_recent.py` | Get post counts (7 days) | Bearer | -| `posts/counts_full_archive.py` | Get post counts (all time) | Bearer | -| `posts/quote_posts.py` | Get quote posts | Bearer | -| `posts/repost.py` | Repost (retweet) | OAuth 1.0a | -| `posts/undo_repost.py` | Undo repost | OAuth 1.0a | -| `posts/reposted_by.py` | Users who reposted | Bearer | -| `posts/like.py` | Like a post | OAuth 1.0a | -| `posts/unlike.py` | Unlike a post | OAuth 1.0a | -| `posts/liking_users.py` | Users who liked a post | Bearer | -| `posts/liked_posts.py` | Posts liked by a user | Bearer | +## Examples + +### Posts +- posts/counts_full_archive.py +- posts/counts_recent.py +- posts/create_post.py +- posts/create_tweet.py +- posts/delete_post.py +- posts/delete_tweet.py +- posts/full_archive_tweet_counts.py +- posts/full-archive-search.py +- posts/get_tweets_with_bearer_token.py +- posts/get_tweets_with_user_context.py +- posts/like_a_tweet.py +- posts/like.py +- posts/liked_posts.py +- posts/liked_tweets.py +- posts/liking_users.py +- posts/lookup.py +- posts/quote_posts.py +- posts/quote_tweets.py +- posts/recent_search.py +- posts/recent_tweet_counts.py +- posts/repost.py +- posts/reposted_by.py +- posts/retweet_a_tweet.py +- posts/retweeted_by.py +- posts/search_full_archive.py +- posts/search_recent.py +- posts/undo_a_retweet.py +- posts/undo_repost.py +- posts/unlike_a_tweet.py +- posts/unlike.py ### Users -| File | Description | Auth | -|------|-------------|------| -| `users/lookup.py` | Look up users by username | Bearer | -| `users/me.py` | Get authenticated user | OAuth 1.0a | -| `users/followers.py` | Get user's followers | Bearer | -| `users/following.py` | Get user's following | Bearer | -| `users/block.py` | Block a user | OAuth 1.0a | -| `users/unblock.py` | Unblock a user | OAuth 1.0a | -| `users/blocked.py` | Get blocked users | OAuth 1.0a | -| `users/mute.py` | Mute a user | OAuth 1.0a | -| `users/unmute.py` | Unmute a user | OAuth 1.0a | -| `users/muted.py` | Get muted users | OAuth 1.0a | +- users/block_a_user.py +- users/block.py +- users/blocked.py +- users/followers_lookup.py +- users/followers.py +- users/following_lookup.py +- users/following.py +- users/get_users_me_user_context.py +- users/get_users_with_bearer_token.py +- users/get_users_with_user_context.py +- users/lookup_blocks.py +- users/lookup_mutes.py +- users/lookup.py +- users/me.py +- users/mute_a_user.py +- users/mute.py +- users/muted.py +- users/unblock_a_user.py +- users/unblock.py +- users/unmute_a_user.py +- users/unmute.py ### Timelines -| File | Description | Auth | -|------|-------------|------| -| `timelines/user_posts.py` | User's posts timeline | Bearer | -| `timelines/user_mentions.py` | User's mentions | Bearer | -| `timelines/home_timeline.py` | Home timeline | OAuth 1.0a | +- timelines/home_timeline.py +- timelines/reverse-chron-home-timeline.py +- timelines/user_mentions.py +- timelines/user_posts.py +- timelines/user_tweets.py ### Streams -| File | Description | Auth | -|------|-------------|------| -| `streams/filtered_stream.py` | Filtered stream with rules | Bearer | -| `streams/sampled_stream.py` | 1% sampled stream | Bearer | +- streams/filtered_stream.py +- streams/sampled_stream.py +- streams/sampled-stream.py + +### Lists +- lists/add_member.py +- lists/create_a_list.py +- lists/create.py +- lists/delete_a_list.py +- lists/delete.py +- lists/follow_list.py +- lists/list-followers-lookup.py +- lists/list-lookup-by-id.py +- lists/list-member-lookup.py +- lists/List-Tweets.py +- lists/lookup.py +- lists/pin_list.py +- lists/Pinned-List.py +- lists/remove_member.py +- lists/unfollow_list.py +- lists/unpin_list.py +- lists/update_a_list.py +- lists/user-list-followed.py +- lists/user-list-memberships.py +- lists/user-owned-list-lookup.py ### Bookmarks -| File | Description | Auth | -|------|-------------|------| -| `bookmarks/lookup.py` | Get bookmarks | OAuth 2.0 | -| `bookmarks/create.py` | Create bookmark | OAuth 2.0 | -| `bookmarks/delete.py` | Delete bookmark | OAuth 2.0 | +- bookmarks/bookmarks_lookup.py +- bookmarks/create_bookmark.py +- bookmarks/create.py +- bookmarks/delete_bookmark.py +- bookmarks/delete.py +- bookmarks/lookup.py ### Spaces -| File | Description | Auth | -|------|-------------|------| -| `spaces/lookup.py` | Look up Spaces | Bearer | -| `spaces/search.py` | Search Spaces | Bearer | - -### Lists -| File | Description | Auth | -|------|-------------|------| -| `lists/lookup.py` | Look up a list | Bearer | -| `lists/create.py` | Create a list | OAuth 1.0a | -| `lists/delete.py` | Delete a list | OAuth 1.0a | +- spaces/lookup.py +- spaces/search_spaces.py +- spaces/search.py +- spaces/spaces_lookup.py ### Direct Messages -| File | Description | Auth | -|------|-------------|------| -| `direct_messages/lookup.py` | Get DM events | OAuth 1.0a | -| `direct_messages/send.py` | Send a DM | OAuth 1.0a | +- direct_messages/get_events_by_conversation.py +- direct_messages/get_one_to_one_conversation_events.py +- direct_messages/get_user_conversation_events.py +- direct_messages/lookup.py +- direct_messages/post_dm_to_conversation.py +- direct_messages/post_group_conversation_dm.py +- direct_messages/post_one_to_one_dm.py +- direct_messages/send.py ### Media -| File | Description | Auth | -|------|-------------|------| -| `media/upload.py` | Upload media | OAuth 1.0a | +- media/media_upload_v2.py +- media/upload.py ### Compliance -| File | Description | Auth | -|------|-------------|------| -| `compliance/create_job.py` | Create compliance job | Bearer | -| `compliance/get_jobs.py` | Get compliance jobs | Bearer | +- compliance/create_compliance_job.py +- compliance/create_job.py +- compliance/download_compliance_results.py +- compliance/get_compliance_job_information_by_id.py +- compliance/get_jobs.py +- compliance/get_list_of_compliance_jobs.py +- compliance/upload_ids.py ### Usage -| File | Description | Auth | -|------|-------------|------| -| `usage/get_usage.py` | Get API usage stats | Bearer | - -## Running Examples - -```bash -# Make sure environment variables are set -python posts/search_recent.py -``` - -## More Information +- usage/get_usage_tweets.py +- usage/get_usage.py -- [X API Documentation](https://developer.x.com/en/docs/twitter-api) -- [X Developer Portal](https://developer.x.com/en/portal/dashboard) diff --git a/python/bookmarks/bookmarks_lookup.py b/python/bookmarks/bookmarks_lookup.py new file mode 100644 index 0000000..e864e22 --- /dev/null +++ b/python/bookmarks/bookmarks_lookup.py @@ -0,0 +1,103 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests.auth import AuthBase, HTTPBasicAuth +from requests_oauthlib import OAuth2Session + +# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = os.environ.get("CLIENT_ID") + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = os.environ.get("CLIENT_SECRET") + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Set the scopes +scopes = ["bookmark.read", "tweet.read", "users.read", "offline.access"] + +# Create a code verifier +code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") +code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + +# Create a code challenge +code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() +code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") +code_challenge = code_challenge.replace("=", "") + +# Start an OAuth 2.0 session +oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + +# Create an authorize URL +auth_url = "https://twitter.com/i/oauth2/authorize" +authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" +) + +# Visit the URL to authorize your App to make requests on behalf of a user +print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" +) +print(authorization_url) + +# Paste in your authorize URL to complete the request +authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" +) + +# Fetch your access token +token_url = "https://api.x.com/2/oauth2/token" + +# The following line of code will only work if you are using a type of App that is a public client +auth = False + +# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. + +# Please remove the comment on the following line if you are using a type of App that is a confidential client +# auth = HTTPBasicAuth(client_id, client_secret) + +token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, +) + +# Your access token +access = token["access_token"] + +# Make a request to the users/me endpoint to get your user ID +user_me = requests.request( + "GET", + "https://api.x.com/2/users/me", + headers={"Authorization": "Bearer {}".format(access)}, +).json() +user_id = user_me["data"]["id"] + +# Make a request to the bookmarks url +url = "https://api.x.com/2/users/{}/bookmarks".format(user_id) +headers = { + "Authorization": "Bearer {}".format(access), + "User-Agent": "BookmarksSampleCode", +} +response = requests.request("GET", url, headers=headers) +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/bookmarks/create_bookmark.py b/python/bookmarks/create_bookmark.py new file mode 100644 index 0000000..56346d9 --- /dev/null +++ b/python/bookmarks/create_bookmark.py @@ -0,0 +1,107 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests.auth import AuthBase, HTTPBasicAuth +from requests_oauthlib import OAuth2Session + +# Replace with a Tweet ID you want to Bookmark +tweet_to_bookmark = {"tweet_id": "1460323737035677698"} + +# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = os.environ.get("CLIENT_ID") + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = os.environ.get("CLIENT_SECRET") + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Set the scopes +scopes = ["bookmark.write", "tweet.read", "users.read", "offline.access"] + +# Create a code verifier +code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") +code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + +# Create a code challenge +code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() +code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") +code_challenge = code_challenge.replace("=", "") + +# Start and OAuth 2.0 session +oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + +# Create an authorize URL +auth_url = "https://twitter.com/i/oauth2/authorize" +authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" +) + +# Visit the URL to authorize your App to make requests on behalf of a user +print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" +) +print(authorization_url) + +# Paste in your authorize URL to complete the request +authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" +) + +# Fetch your access token +token_url = "https://api.x.com/2/oauth2/token" + +# The following line of code will only work if you are using a type of App that is a public client +auth = False + +# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. + +# Please remove the comment on the following line if you are using a type of App that is a confidential client +# auth = HTTPBasicAuth(client_id, client_secret) + +token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, +) + +# Your access token +access = token["access_token"] + +# Make a request to the users/me endpoint to get your user ID +user_me = requests.request( + "GET", + "https://api.x.com/2/users/me", + headers={"Authorization": "Bearer {}".format(access)}, +).json() +user_id = user_me["data"]["id"] + +# Make a request to the bookmarks url +url = "https://api.x.com/2/users/{}/bookmarks".format(user_id) +headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "BookmarksSampleCode", +} +response = requests.request("POST", url, headers=headers, json=tweet_to_bookmark) +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/bookmarks/delete_bookmark.py b/python/bookmarks/delete_bookmark.py new file mode 100644 index 0000000..fae427b --- /dev/null +++ b/python/bookmarks/delete_bookmark.py @@ -0,0 +1,109 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests.auth import AuthBase, HTTPBasicAuth +from requests_oauthlib import OAuth2Session + +# Replace with a Tweet ID you want to remove Bookmark of +bookmarked_tweet_id = "1460323737035677698" + +# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = os.environ.get("CLIENT_ID") + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = os.environ.get("CLIENT_SECRET") + + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Set the scopes +scopes = ["bookmark.write", "tweet.read", "users.read", "offline.access"] + +# Create a code verifier +code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") +code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + +# Create a code challenge +code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() +code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") +code_challenge = code_challenge.replace("=", "") + +# Start and OAuth 2.0 session +oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + +# Create an authorize URL +auth_url = "https://twitter.com/i/oauth2/authorize" +authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" +) + +# Visit the URL to authorize your App to make requests on behalf of a user +print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" +) +print(authorization_url) + +# Paste in your authorize URL to complete the request +authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" +) + +# Fetch your access token +token_url = "https://api.x.com/2/oauth2/token" + +# The following line of code will only work if you are using a type of App that is a public client +auth = False + +# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. + +# Please remove the comment on the following line if you are using a type of App that is a confidential client +# auth = HTTPBasicAuth(client_id, client_secret) + +token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, +) + +# Your access token +access = token["access_token"] + +# Make a request to the users/me endpoint to get the user ID of the authenticated user +user_me = requests.request( + "GET", + "https://api.x.com/2/users/me", + headers={"Authorization": "Bearer {}".format(access)}, +).json() +user_id = user_me["data"]["id"] + +# Make a request to the bookmarks url +url = "https://api.x.com/2/users/{}/bookmarks/{}".format( + user_id, bookmarked_tweet_id +) +headers = { + "Authorization": "Bearer {}".format(access), + "User-Agent": "BookmarksSampleCode", +} +response = requests.request("DELETE", url, headers=headers) +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/compliance/create_compliance_job.py b/python/compliance/create_compliance_job.py new file mode 100644 index 0000000..f0ceca4 --- /dev/null +++ b/python/compliance/create_compliance_job.py @@ -0,0 +1,40 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +compliance_job_url = "https://api.x.com/2/compliance/jobs" + +# For User Compliance Job, replace the type value with users instead of tweets +# Also replace the name value with your desired job name +body = {"type": "tweets", "name": "my_batch_compliance_job"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2BatchCompliancePython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("POST", url, auth=bearer_oauth, json=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(compliance_job_url, body) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/compliance/download_compliance_results.py b/python/compliance/download_compliance_results.py new file mode 100644 index 0000000..7c46399 --- /dev/null +++ b/python/compliance/download_compliance_results.py @@ -0,0 +1,23 @@ +import requests + +# Replace with your job download_url +download_url = '' + + +def connect_to_endpoint(url): + response = requests.request("GET", url) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.text + + +def main(): + response = connect_to_endpoint(download_url) + entries = response.splitlines() + for entry in entries: + print(entry) + + +if __name__ == "__main__": + main() diff --git a/python/compliance/get_compliance_job_information_by_id.py b/python/compliance/get_compliance_job_information_by_id.py new file mode 100644 index 0000000..5d46e72 --- /dev/null +++ b/python/compliance/get_compliance_job_information_by_id.py @@ -0,0 +1,39 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +# Replace with your job ID below +job_id = '' + +compliance_job_url = f"https://api.x.com/2/compliance/jobs/{job_id}".format(job_id) + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2BatchCompliancePython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(compliance_job_url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/compliance/get_list_of_compliance_jobs.py b/python/compliance/get_list_of_compliance_jobs.py new file mode 100644 index 0000000..54a9c01 --- /dev/null +++ b/python/compliance/get_list_of_compliance_jobs.py @@ -0,0 +1,39 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +compliance_job_url = "https://api.x.com/2/compliance/jobs" + +# For User Compliance job, replace the value for type with users +query_params = {"type": "tweets"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2BatchCompliancePython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(compliance_job_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/compliance/upload_ids.py b/python/compliance/upload_ids.py new file mode 100644 index 0000000..4c41aba --- /dev/null +++ b/python/compliance/upload_ids.py @@ -0,0 +1,26 @@ +import requests + +# Replace with your job download_url +upload_url = '' + +# Replace with your file path that contains the list of Tweet IDs or User IDs, one ID per line +file_path = '' + +headers = {'Content-Type': "text/plain"} + + +def connect_to_endpoint(url): + response = requests.put(url, data=open(file_path, 'rb'), headers=headers) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.text + + +def main(): + response = connect_to_endpoint(upload_url) + print(response) + + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/get_events_by_conversation.py b/python/direct_messages/get_events_by_conversation.py new file mode 100644 index 0000000..93515f7 --- /dev/null +++ b/python/direct_messages/get_events_by_conversation.py @@ -0,0 +1,107 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +# This example is set up to retrieve Direct Message events by conversation ID. This supports both +# one-to-one and group conversations. +GET_DMS_EVENTS_URL = "https://api.x.com/2/dm_conversations/:dm_conversation_id/dm_events" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = '' +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- +# This variable specifies the conversation to retrieve. A more ready-to-be used example would +# have this passed in from some calling code. +# What is the ID of the conversatikon to retrieve? +dm_conversation_id = "1512210732774948865" +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start and OAuth 2.0 session + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # Your access token + access = token["access_token"] + + return access + +def get_events_by_conservation_id(dm_conversation_id): + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = GET_DMS_EVENTS_URL.replace(':dm_conversation_id', str(dm_conversation_id)) + + response = requests.request("GET", request_url, headers=headers) + + if response.status_code != 200: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + return response + +def main(): + response = get_events_by_conservation_id(dm_conversation_id) + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/get_one_to_one_conversation_events.py b/python/direct_messages/get_one_to_one_conversation_events.py new file mode 100644 index 0000000..b03f552 --- /dev/null +++ b/python/direct_messages/get_one_to_one_conversation_events.py @@ -0,0 +1,108 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +# This example is set up to retrieve Direct Message conversation events associated with a one-to-one message. +# Currently, the v2 DM endpoints support three conversation event types: MessageCreate, ParticipantsJoin, and +# ParticipantsLeave. +GET_DM_EVENTS_URL = "https://api.x.com/2/dm_conversations/with/:participant_id/dm_events" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = '' +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- +# This variable indicates the participant of the one-to-one conversation. A more ready-to-be used example would +# have this passed in from some calling code. +# Who is this one-to-one conversation with? +participant_id = "906948460078698496" +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start and OAuth 2.0 session + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # Your access token + access = token["access_token"] + + return access + +def get_one_to_one_conversation_events(participant_id): + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = GET_DM_EVENTS_URL.replace(':participant_id', str(participant_id)) + + response = requests.request("GET", request_url, headers=headers) + + if response.status_code != 200: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + return response + +def main(): + response = get_one_to_one_conversation_events(participant_id) + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/get_user_conversation_events.py b/python/direct_messages/get_user_conversation_events.py new file mode 100644 index 0000000..b5bc8c5 --- /dev/null +++ b/python/direct_messages/get_user_conversation_events.py @@ -0,0 +1,102 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +# This example is set up to retrieve Direct Message events of the authenticating user. This supports both +# one-to-one and group conversations. +GET_DM_EVENTS_URL = "https://api.x.com/2/dm_events" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = "" +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier. + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge. + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start an OAuth 2.0 session. + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL. + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user. + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request. + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token. + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client. + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # The access token. + access = token["access_token"] + + return access + +def get_user_conversation_events(): + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = GET_DM_EVENTS_URL + + response = requests.request("GET", request_url, headers=headers) + + if response.status_code != 200: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + return response + +def main(): + response = get_user_conversation_events() + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/post_dm_to_conversation.py b/python/direct_messages/post_dm_to_conversation.py new file mode 100644 index 0000000..18d6af3 --- /dev/null +++ b/python/direct_messages/post_dm_to_conversation.py @@ -0,0 +1,113 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +#This example is set up to add a DM to a specified conversation by referencing its ID. +POST_DM_URL = "https://api.x.com/2/dm_conversations/:dm_conversation_id/messages" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = '' +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- +# These variables indicate the conversation that the message should be added to. A more ready-to-be used example would +# have these passed in from some calling code. +# Provide the ID of the conversation this message should be added to. +dm_conversation_id = "1512210732774948865" +#Set the text of the message to be sent. +text_message = "Hi, I am adding a message to an existing conversation by referencing its ID." +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier. + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge. + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start an OAuth 2.0 session. + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL. + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user. + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request. + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token. + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # The access token. + access = token["access_token"] + + return access + +def add_dm_to_conversation(dm_text, dm_conversation_id): + request_body = {} + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = POST_DM_URL.replace(':dm_conversation_id', str(dm_conversation_id)) + request_body['text'] = dm_text + json_body = json.dumps(request_body) + + #Send DM + response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) + + if response.status_code != 201: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + + return response + +def main(): + response = add_dm_to_conversation(text_message, dm_conversation_id) + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/post_group_conversation_dm.py b/python/direct_messages/post_group_conversation_dm.py new file mode 100644 index 0000000..135a9e5 --- /dev/null +++ b/python/direct_messages/post_group_conversation_dm.py @@ -0,0 +1,116 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +#This example is set up to create a new group conversation and add a new DM to it. +POST_DM_URL = "https://api.x.com/2/dm_conversations" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = '' +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- +# These variables indicate the participants of the new group conversation and the message to add. A more ready-to-be +# used example would have these passed in from some calling code. +#Who is in this group conversation? Reference their User IDs. +participant_ids = ["944480690","906948460078698496"] +#Set the text of the message to be sent. +text_message = "Hi, I am creating a new *group* conversation, and starting it with the this message." +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier. + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge. + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start an OAuth 2.0 session. + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL. + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user. + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request. + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token. + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client. + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # The access token + access = token["access_token"] + + return access + +def create_new_group_conversation_with_dm(dm_text, participant_ids): + request_body = {} + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = POST_DM_URL + request_body['message'] = {} + request_body['message']['text'] = dm_text + request_body['participant_ids'] = participant_ids + request_body['conversation_type'] = "Group" + json_body = json.dumps(request_body) + + #Send DM + response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) + + if response.status_code != 201: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + + return response + +def main(): + response = create_new_group_conversation_with_dm(text_message, participant_ids) + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/direct_messages/post_one_to_one_dm.py b/python/direct_messages/post_one_to_one_dm.py new file mode 100644 index 0000000..da59ba4 --- /dev/null +++ b/python/direct_messages/post_one_to_one_dm.py @@ -0,0 +1,114 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests_oauthlib import OAuth2Session + +#This example is set up to add a new DM to a one-to-one conversation. +POST_DM_URL = "https://api.x.com/2/dm_conversations/with/:participant_id/messages" + +#----------------------------------------------------------------------------------------------------------------------- +# These variables need to be updated to the setting that match how your Twitter App is set-up at +# https://developer.twitter.com/en/portal/dashboard. These will not change from run-by-run. +client_id = '' +#This must match *exactly* the redirect URL specified in the Developer Portal. +redirect_uri = "https://www.example.com" +#----------------------------------------------------------------------------------------------------------------------- +# These variables indicate the participant of the one-to-one conversation and the message to add. A more ready-to-be +# used example would have these passed in from some calling code. +#Who is this DM being sent to? Reference their User ID. +participant_id = "944480690" +#Set the text of the message to be sent. +text_message = "Hi, I am DMing you using the v2 DM one-to-one endpoint." +#----------------------------------------------------------------------------------------------------------------------- + +def handle_oauth(): + + # Set the scopes needed to be granted by the authenticating user. + scopes = ["dm.read", "dm.write", "tweet.read", "users.read", "offline.access"] + + # Create a code verifier + code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") + code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + + # Create a code challenge + code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() + code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") + code_challenge = code_challenge.replace("=", "") + + # Start an OAuth 2.0 session + oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + + # Create an authorize URL + auth_url = "https://twitter.com/i/oauth2/authorize" + authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" + ) + + # Visit the URL to authorize your App to make requests on behalf of a user + print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" + ) + print(authorization_url) + + # Paste in your authorize URL to complete the request + authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" + ) + + # Fetch your access token + token_url = "https://api.x.com/2/oauth2/token" + + # The following line of code will only work if you are using a type of App that is a public client + auth = False + + token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, + ) + + # Your access token + access = token["access_token"] + + return access + +def post_dm_to_one_to_one_conversation(participant_id): + + request_body = {} + + access = handle_oauth() + + headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "TwitterDevSampleCode", + "X-TFE-Experiment-environment": "staging1", + "Dtab-Local": "/s/gizmoduck/test-users-temporary => /s/gizmoduck/gizmoduck" + } + + request_url = POST_DM_URL.replace(':participant_id', str(participant_id)) + request_body['text'] = text_message + json_body = json.dumps(request_body) + + #Send DM + response = requests.request("POST", request_url, headers=headers, json=json.loads(json_body)) + + if response.status_code != 201: + print("Request returned an error: {} {}".format(response.status_code, response.text)) + else: + print(f"Response code: {response.status_code}") + + return response + +def main(): + response = post_dm_to_one_to_one_conversation(participant_id) + print(json.dumps(json.loads(response.text), indent=4, sort_keys=True)) + +if __name__ == "__main__": + main() diff --git a/python/lists/List-Tweets.py b/python/lists/List-Tweets.py new file mode 100644 index 0000000..dca8430 --- /dev/null +++ b/python/lists/List-Tweets.py @@ -0,0 +1,55 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + tweet_fields = "tweet.fields=lang,author_id" + # Be sure to replace list-id with any List ID + id = "list-id" + url = "https://api.x.com/2/lists/{}/tweets".format(id) + return url, tweet_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListTweetsLookupPython" + return r + + +def connect_to_endpoint(url, tweet_fields): + response = requests.request( + "GET", url, auth=bearer_oauth, params=tweet_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, tweet_fields = create_url() + json_response = connect_to_endpoint(url, tweet_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/Pinned-List.py b/python/lists/Pinned-List.py new file mode 100644 index 0000000..898d63f --- /dev/null +++ b/python/lists/Pinned-List.py @@ -0,0 +1,78 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# List fields are adjustable, options include: +# created_at, description, owner_id, +# private, follower_count, member_count, +list_fields = "list.fields=created_at,description,private" + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.get( + "https://api.x.com/2/users/{}/pinned_lists".format(id), params=list_fields) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/add_member.py b/python/lists/add_member.py new file mode 100644 index 0000000..fe985f1 --- /dev/null +++ b/python/lists/add_member.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-list-id with your own list ID or one of an authenticating user + +id = "your-list-id" + +# Be sure to replace user-id-to-add with the user id you wish to add. +payload = {"user_id": "user-id-to-add"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/lists/{}/members".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/create_a_list.py b/python/lists/create_a_list.py new file mode 100644 index 0000000..cb4d5b0 --- /dev/null +++ b/python/lists/create_a_list.py @@ -0,0 +1,76 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to add replace name-of-list with the name you wish to call the list. +# description and private keys are optional +payload = { "name": "name-of-list", + "description": "description-of-list", + "private": False} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/lists", json=payload +) + +if response.status_code != 201: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/delete_a_list.py b/python/lists/delete_a_list.py new file mode 100644 index 0000000..c00bded --- /dev/null +++ b/python/lists/delete_a_list.py @@ -0,0 +1,75 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-list-id with the id of the list you wish to delete. The authenticated user must own the list in order to delete + +id = "your-list-id" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/lists/{}".format(id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/follow_list.py b/python/lists/follow_list.py new file mode 100644 index 0000000..d52adc0 --- /dev/null +++ b/python/lists/follow_list.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-follow with the list id you wish to follow. +payload = {"list_id": "list-id-to-follow"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/followed_lists".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/list-followers-lookup.py b/python/lists/list-followers-lookup.py new file mode 100644 index 0000000..85566d0 --- /dev/null +++ b/python/lists/list-followers-lookup.py @@ -0,0 +1,51 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + user_fields = "user.fields=created_at,description,verified" + # You can replace list-id with the List ID you wish to find followers of. + id = "list-id" + url = "https://api.x.com/2/lists/{}/followers".format(id) + return url, user_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListFollowersLookupPython" + return r + + +def connect_to_endpoint(url, user_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, user_fields = create_url() + json_response = connect_to_endpoint(url, user_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/list-lookup-by-id.py b/python/lists/list-lookup-by-id.py new file mode 100644 index 0000000..6f47eff --- /dev/null +++ b/python/lists/list-lookup-by-id.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + list_fields = "list.fields=created_at,follower_count" + # You can replace the ID given with the List ID you wish to lookup. + id = "list-id" + url = "https://api.x.com/2/lists/{}".format(id) + return url, list_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListLookupPython" + return r + + +def connect_to_endpoint(url, list_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, list_fields = create_url() + json_response = connect_to_endpoint(url, list_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/list-member-lookup.py b/python/lists/list-member-lookup.py new file mode 100644 index 0000000..0f10dd3 --- /dev/null +++ b/python/lists/list-member-lookup.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + user_fields = "user.fields=created_at,description,verified" + # You can replace list-id with the List ID you wish to find members of. + id = "list-id" + url = "https://api.x.com/2/lists/{}/members".format(id) + return url, user_fields + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListMembersLookupPython" + return r + + +def connect_to_endpoint(url, user_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, user_fields = create_url() + json_response = connect_to_endpoint(url, user_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/pin_list.py b/python/lists/pin_list.py new file mode 100644 index 0000000..20a03b4 --- /dev/null +++ b/python/lists/pin_list.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-pin with the list id you wish to pin. +payload = {"list_id": "list-id-to-pin"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/pinned_lists".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/remove_member.py b/python/lists/remove_member.py new file mode 100644 index 0000000..cf51b34 --- /dev/null +++ b/python/lists/remove_member.py @@ -0,0 +1,78 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-list-id with your own list ID or one of an authenticated user +id = "your-list-id" + +# Be sure to add replace user-id-to-remove with the id of the user you wish to remove. +# You can find a user ID by using the user lookup endpoint +user_id = "user-id-to-remove" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/lists/{}/members/{}".format(id, user_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/unfollow_list.py b/python/lists/unfollow_list.py new file mode 100644 index 0000000..d28b62a --- /dev/null +++ b/python/lists/unfollow_list.py @@ -0,0 +1,78 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-unfollow with the id of the user you wish to unfollow. +list_id = "list-id-to-unfollow" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/followed_lists/{}".format(id, list_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/unpin_list.py b/python/lists/unpin_list.py new file mode 100644 index 0000000..03e76d7 --- /dev/null +++ b/python/lists/unpin_list.py @@ -0,0 +1,78 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-unpin with the id of the user you wish to unpin. +list_id = "list-id-to-unpin" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/pinned_lists/{}".format(id, list_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/update_a_list.py b/python/lists/update_a_list.py new file mode 100644 index 0000000..8abf2ba --- /dev/null +++ b/python/lists/update_a_list.py @@ -0,0 +1,81 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to add replace update-name-of-list with the name you wish to call the list. +# name, description and private are all optional +payload = { "name": "update-name-of-list", + "description": "update-description-of-list", + "private": False} + + +# Be sure to replace your-list-id with the id of the list you wish to update. The authenticated user must own the list in order to update + +id = "your-list-id" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.put( + "https://api.x.com/2/lists/{}".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/lists/user-list-followed.py b/python/lists/user-list-followed.py new file mode 100644 index 0000000..f28b3be --- /dev/null +++ b/python/lists/user-list-followed.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + list_fields = "list.fields=created_at,follower_count" + # You can replace the user-id with any valid User ID you wish to find what Lists they are following. + id = "user-id" + url = "https://api.x.com/2/users/{}/followed_lists".format(id) + return url, list_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2userListMembershipsPython" + return r + + +def connect_to_endpoint(url, list_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, list_fields = create_url() + json_response = connect_to_endpoint(url, list_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/user-list-memberships.py b/python/lists/user-list-memberships.py new file mode 100644 index 0000000..3455aaa --- /dev/null +++ b/python/lists/user-list-memberships.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + list_fields = "list.fields=created_at,follower_count" + # You can replace the user-id with any valid User ID you wish to find what Lists they are members of. + id = "user-id" + url = "https://api.x.com/2/users/{}/list_memberships".format(id) + return url, list_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2userListMembershipsPython" + return r + + +def connect_to_endpoint(url, list_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, list_fields = create_url() + json_response = connect_to_endpoint(url, list_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/lists/user-owned-list-lookup.py b/python/lists/user-owned-list-lookup.py new file mode 100644 index 0000000..3bbcd99 --- /dev/null +++ b/python/lists/user-owned-list-lookup.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + list_fields = "list.fields=created_at,follower_count" + # You can replace user-id with any valid User ID to see if they own any Lists. + id = "user-id" + url = "https://api.x.com/2/users/{}/owned_lists".format(id) + return url, list_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2ListLookupPython" + return r + + +def connect_to_endpoint(url, list_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=list_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, list_fields = create_url() + json_response = connect_to_endpoint(url, list_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/media/media_upload_v2.py b/python/media/media_upload_v2.py new file mode 100644 index 0000000..0b28df2 --- /dev/null +++ b/python/media/media_upload_v2.py @@ -0,0 +1,229 @@ +import os +import sys +import base64 +import hashlib +import re +import time +import requests +from requests_oauthlib import OAuth2Session + +MEDIA_ENDPOINT_URL = 'https://api.x.com/2/media/upload' +POST_TO_X_URL = 'https://api.x.com/2/tweets' + +# Replace with path to file +VIDEO_FILENAME = 'REPLACE_ME' + +# You will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = os.environ.get("CLIENT_ID") + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = os.environ.get("CLIENT_SECRET") + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Set the scopes +scopes = ["media.write", "users.read", "tweet.read", "tweet.write", "offline.access"] + +# Create a code verifier +code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") +code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + +# Create a code challenge +code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() +code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") +code_challenge = code_challenge.replace("=", "") + +# Start and OAuth 2.0 session +oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + +# Create an authorize URL +auth_url = "https://x.com/i/oauth2/authorize" +authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" +) + +# Visit the URL to authorize your App to make requests on behalf of a user +print( + "Visit the following URL to authorize your App on behalf of your X handle in a browser:" +) +print(authorization_url) + +# Paste in your authorize URL to complete the request +authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" +) + +# Fetch your access token +token_url = "https://api.x.com/2/oauth2/token" + +# The following line of code will only work if you are using a type of App that is a public client +auth = False + +# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. + +# Please remove the comment on the following line if you are using a type of App that is a confidential client +# auth = HTTPBasicAuth(client_id, client_secret) + +token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, +) + +# Your access token +access = token["access_token"] + +headers = { + "Authorization": "Bearer {}".format(access), + "Content-Type": "application/json", + "User-Agent": "MediaUploadSampleCode", +} + + +class VideoPost(object): + + def __init__(self, file_name): + # Defines video Post properties + self.video_filename = file_name + self.total_bytes = os.path.getsize(self.video_filename) + self.media_id = None + self.processing_info = None + + def upload_init(self): + # Initializes Upload + print('INIT') + + request_data = { + 'command': 'INIT', + 'media_type': 'video/mp4', + 'total_bytes': self.total_bytes, + 'media_category': 'tweet_video' + } + + req = requests.post(url=MEDIA_ENDPOINT_URL, params=request_data, headers=headers) + print(req.status_code) + print(req.text) + media_id = req.json()['data']['id'] + + self.media_id = media_id + + print('Media ID: %s' % str(media_id)) + + def upload_append(self): + segment_id = 0 + bytes_sent = 0 + with open(self.video_filename, 'rb') as file: + while bytes_sent < self.total_bytes: + chunk = file.read(4 * 1024 * 1024) # 4MB chunk size + + print('APPEND') + + files = {'media': ('chunk', chunk, 'application/octet-stream')} + + data = { + 'command': 'APPEND', + 'media_id': self.media_id, + 'segment_index': segment_id + } + + headers = { + "Authorization": f"Bearer {access}", + "User-Agent": "MediaUploadSampleCode", + } + + req = requests.post(url=MEDIA_ENDPOINT_URL, data=data, files=files, headers=headers) + + if req.status_code < 200 or req.status_code > 299: + print(req.status_code) + print(req.text) + sys.exit(0) + + segment_id += 1 + bytes_sent = file.tell() + + print(f'{bytes_sent} of {self.total_bytes} bytes uploaded') + + print('Upload chunks complete.') + + def upload_finalize(self): + + # Finalizes uploads and starts video processing + print('FINALIZE') + + request_data = { + 'command': 'FINALIZE', + 'media_id': self.media_id + } + + req = requests.post(url=MEDIA_ENDPOINT_URL, params=request_data, headers=headers) + + print(req.json()) + + self.processing_info = req.json()['data'].get('processing_info', None) + self.check_status() + + def check_status(self): + # Checks video processing status + if self.processing_info is None: + return + + state = self.processing_info['state'] + + print('Media processing status is %s ' % state) + + if state == u'succeeded': + return + + if state == u'failed': + sys.exit(0) + + check_after_secs = self.processing_info['check_after_secs'] + + print('Checking after %s seconds' % str(check_after_secs)) + time.sleep(check_after_secs) + + print('STATUS') + + request_params = { + 'command': 'STATUS', + 'media_id': self.media_id + } + + req = requests.get(url=MEDIA_ENDPOINT_URL, params=request_params, headers=headers) + + self.processing_info = req.json()['data'].get('processing_info', None) + self.check_status() + + def post(self): + + # Publishes Post with attached video + payload = { + 'text': 'I just uploaded a video with the media upload v2 @XDevelopers API.', + 'media': { + 'media_ids': [self.media_id] + } + } + + req = requests.post(url=POST_TO_X_URL, json=payload, headers=headers) + + print(req.json()) + + +if __name__ == '__main__': + videoPost = VideoPost(VIDEO_FILENAME) + videoPost.upload_init() + videoPost.upload_append() + videoPost.upload_finalize() + videoPost.post() diff --git a/python/posts/create_tweet.py b/python/posts/create_tweet.py new file mode 100644 index 0000000..92c570b --- /dev/null +++ b/python/posts/create_tweet.py @@ -0,0 +1,73 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to add replace the text of the with the text you wish to Tweet. You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. +payload = {"text": "Hello world!"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token?oauth_callback=oob&x_auth_access_type=write" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/tweets", + json=payload, +) + +if response.status_code != 201: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/delete_tweet.py b/python/posts/delete_tweet.py new file mode 100644 index 0000000..2184284 --- /dev/null +++ b/python/posts/delete_tweet.py @@ -0,0 +1,73 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace tweet-id-to-delete with the id of the Tweet you wish to delete. The authenticated user must own the list in order to delete + +id = "tweet-id-to-delete" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete("https://api.x.com/2/tweets/{}".format(id)) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json_response) diff --git a/python/posts/full-archive-search.py b/python/posts/full-archive-search.py new file mode 100644 index 0000000..785c487 --- /dev/null +++ b/python/posts/full-archive-search.py @@ -0,0 +1,40 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/tweets/search/all" + +# Optional params: start_time,end_time,since_id,until_id,max_results,next_token, +# expansions,tweet.fields,media.fields,poll.fields,place.fields,user.fields +query_params = {'query': '(from:twitterdev -is:retweet) OR #twitterdev','tweet.fields': 'author_id'} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FullArchiveSearchPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", search_url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(search_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/python/posts/full_archive_tweet_counts.py b/python/posts/full_archive_tweet_counts.py new file mode 100644 index 0000000..697a0be --- /dev/null +++ b/python/posts/full_archive_tweet_counts.py @@ -0,0 +1,39 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/tweets/counts/all" + +# Optional params: start_time,end_time,since_id,until_id,next_token,granularity +query_params = {'query': 'from:twitterdev','granularity': 'day', 'start_time': '2021-01-01T00:00:00Z'} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FullArchiveTweetCountsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", search_url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(search_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/python/posts/get_tweets_with_bearer_token.py b/python/posts/get_tweets_with_bearer_token.py new file mode 100644 index 0000000..e646f70 --- /dev/null +++ b/python/posts/get_tweets_with_bearer_token.py @@ -0,0 +1,55 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + tweet_fields = "tweet.fields=lang,author_id" + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + ids = "ids=1278747501642657792,1255542774432063488" + # You can adjust ids to include a single Tweets. + # Or you can add to up to 100 comma-separated IDs + url = "https://api.x.com/2/tweets?{}&{}".format(ids, tweet_fields) + return url + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2TweetLookupPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/get_tweets_with_user_context.py b/python/posts/get_tweets_with_user_context.py new file mode 100644 index 0000000..8ab866e --- /dev/null +++ b/python/posts/get_tweets_with_user_context.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# You can adjust ids to include a single Tweets +# Or you can add to up to 100 comma-separated IDs +params = {"ids": "1278747501642657792", "tweet.fields": "created_at"} +# Tweet fields are adjustable. +# Options include: +# attachments, author_id, context_annotations, +# conversation_id, created_at, entities, geo, id, +# in_reply_to_user_id, lang, non_public_metrics, organic_metrics, +# possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, +# source, text, and withheld + +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +response = oauth.get( + "https://api.x.com/2/tweets", params=params +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/like_a_tweet.py b/python/posts/like_a_tweet.py new file mode 100644 index 0000000..00a24ce --- /dev/null +++ b/python/posts/like_a_tweet.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace Tweet ID given with the Tweet ID you wish to like. +# You can find a Tweet ID by using the Tweet lookup endpoint +payload = {"tweet_id": "1354143047324299264"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/likes".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/liked_tweets.py b/python/posts/liked_tweets.py new file mode 100644 index 0000000..b668621 --- /dev/null +++ b/python/posts/liked_tweets.py @@ -0,0 +1,58 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + tweet_fields = "tweet.fields=lang,author_id" + # Be sure to replace your-user-id with your own user ID or one of an authenticating user + # You can find a user ID by using the user lookup endpoint + id = "your-user-id" + # You can adjust ids to include a single Tweets. + # Or you can add to up to 100 comma-separated IDs + url = "https://api.x.com/2/users/{}/liked_tweets".format(id) + return url, tweet_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2LikedTweetsPython" + return r + + +def connect_to_endpoint(url, tweet_fields): + response = requests.request( + "GET", url, auth=bearer_oauth, params=tweet_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, tweet_fields = create_url() + json_response = connect_to_endpoint(url, tweet_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/liking_users.py b/python/posts/liking_users.py index 9e7350d..1b08116 100644 --- a/python/posts/liking_users.py +++ b/python/posts/liking_users.py @@ -1,51 +1,52 @@ -""" -Users Who Liked a Post - X API v2 -================================= -Endpoint: GET https://api.x.com/2/tweets/:id/liking_users -Docs: https://developer.x.com/en/docs/twitter-api/tweets/likes/api-reference/get-tweets-id-liking_users - -Authentication: Bearer Token (App-only) or OAuth (User Context) -Required env vars: BEARER_TOKEN -""" - import requests import os import json +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Replace with the post ID you want to get liking users for - post_id = "1354143047324299264" - return "https://api.x.com/2/tweets/{}/liking_users".format(post_id) - - -def get_params(): - return {"user.fields": "created_at"} + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + user_fields = "user.fields=created_at,description" + # You can replace the ID given with the Tweet ID you wish to like. + # You can find an ID by using the Tweet lookup endpoint + id = "1354143047324299264" + # You can adjust ids to include a single Tweets. + # Or you can add to up to 100 comma-separated IDs + url = "https://api.x.com/2/tweets/{}/liking_users".format(id) + return url, user_fields def bearer_oauth(r): """ Method required by bearer token authentication. """ + r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2LikingUsersPython" return r -def connect_to_endpoint(url, params): - response = requests.request("GET", url, auth=bearer_oauth, params=params) +def connect_to_endpoint(url, user_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) print(response.status_code) if response.status_code != 200: - raise Exception(response.status_code, response.text) + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) return response.json() def main(): - url = create_url() - params = get_params() - json_response = connect_to_endpoint(url, params) + url, tweet_fields = create_url() + json_response = connect_to_endpoint(url, tweet_fields) print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/quote_tweets.py b/python/posts/quote_tweets.py new file mode 100644 index 0000000..a56204c --- /dev/null +++ b/python/posts/quote_tweets.py @@ -0,0 +1,58 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' + + +def auth(): + return os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with Tweet ID below + tweet_id = 20 + return "https://api.x.com/2/tweets/{}/quote_tweets".format(tweet_id) + + +def get_params(): + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + return {"tweet.fields": "created_at"} + + +def create_headers(bearer_token): + headers = {"Authorization": "Bearer {}".format(bearer_token)} + return headers + + +def connect_to_endpoint(url, headers, params): + response = requests.request("GET", url, headers=headers, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + bearer_token = auth() + url = create_url() + headers = create_headers(bearer_token) + params = get_params() + json_response = connect_to_endpoint(url, headers, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() + \ No newline at end of file diff --git a/python/posts/recent_search.py b/python/posts/recent_search.py new file mode 100644 index 0000000..58b19a9 --- /dev/null +++ b/python/posts/recent_search.py @@ -0,0 +1,39 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/tweets/search/recent" + +# Optional params: start_time,end_time,since_id,until_id,max_results,next_token, +# expansions,tweet.fields,media.fields,poll.fields,place.fields,user.fields +query_params = {'query': '(from:twitterdev -is:retweet) OR #twitterdev','tweet.fields': 'author_id'} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2RecentSearchPython" + return r + +def connect_to_endpoint(url, params): + response = requests.get(url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(search_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/recent_tweet_counts.py b/python/posts/recent_tweet_counts.py new file mode 100644 index 0000000..2b94f03 --- /dev/null +++ b/python/posts/recent_tweet_counts.py @@ -0,0 +1,39 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/tweets/counts/recent" + +# Optional params: start_time,end_time,since_id,until_id,next_token,granularity +query_params = {'query': 'from:twitterdev','granularity': 'day'} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2RecentTweetCountsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + json_response = connect_to_endpoint(search_url, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/retweet_a_tweet.py b/python/posts/retweet_a_tweet.py new file mode 100644 index 0000000..40c218b --- /dev/null +++ b/python/posts/retweet_a_tweet.py @@ -0,0 +1,78 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace the given Tweet ID with your the Tweet ID you want to Retweet +# You can find a Tweet ID by using the Tweet lookup endpoint +payload = {"tweet_id": "1412865600439738368"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/retweets".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/retweeted_by.py b/python/posts/retweeted_by.py new file mode 100644 index 0000000..9876a36 --- /dev/null +++ b/python/posts/retweeted_by.py @@ -0,0 +1,56 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' + + +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + user_fields = "user.fields=created_at,description" + # You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for + # You can find an ID by using the Tweet lookup endpoint + id = "1354143047324299264" + # You can adjust ids to include a single Tweets. + # Or you can add to up to 100 comma-separated IDs + url = "https://api.x.com/2/tweets/{}/retweeted_by".format(id) + return url, user_fields + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2RetweetedByPython" + return r + + +def connect_to_endpoint(url, user_fields): + response = requests.request("GET", url, auth=bearer_oauth, params=user_fields) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url, user_fields = create_url() + json_response = connect_to_endpoint(url, user_fields) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/posts/undo_a_retweet.py b/python/posts/undo_a_retweet.py new file mode 100644 index 0000000..51fe32d --- /dev/null +++ b/python/posts/undo_a_retweet.py @@ -0,0 +1,79 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace the given Tweet ID with your the Tweet ID you want to Retweet +# You can find a Tweet ID by using the Tweet lookup endpoint +source_tweet_id = "1412865600439738368" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/retweets/{}".format(id, source_tweet_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/posts/unlike_a_tweet.py b/python/posts/unlike_a_tweet.py new file mode 100644 index 0000000..91ff611 --- /dev/null +++ b/python/posts/unlike_a_tweet.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace Tweet ID given with the Tweet ID you wish to like. +# You can find a Tweet ID by using the Tweet lookup endpoint +tweet_id = "1354143047324299264" + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/likes/{}".format(id, tweet_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/requirements.txt b/python/requirements.txt index f4803a5..a85ab73 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -1,10 +1,2 @@ -# X API v2 Python Examples - Dependencies - -# HTTP client requests>=2.28.0 - -# OAuth 1.0a authentication requests-oauthlib>=1.3.0 - -# OAuth 2.0 with PKCE (for bookmarks and other OAuth 2.0 endpoints) -# oauthlib>=3.2.0 diff --git a/python/spaces/search_spaces.py b/python/spaces/search_spaces.py new file mode 100644 index 0000000..d0c6340 --- /dev/null +++ b/python/spaces/search_spaces.py @@ -0,0 +1,40 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/spaces/search" + +search_term = 'NBA' # Replace this value with your search term + +# Optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at +query_params = {'query': search_term, 'space.fields': 'title,created_at', 'expansions': 'creator_id'} + + +def create_headers(bearer_token): + headers = { + "Authorization": "Bearer {}".format(bearer_token), + "User-Agent": "v2SpacesSearchPython" + } + return headers + + +def connect_to_endpoint(url, headers, params): + response = requests.request("GET", search_url, headers=headers, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + headers = create_headers(bearer_token) + json_response = connect_to_endpoint(search_url, headers, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/python/spaces/spaces_lookup.py b/python/spaces/spaces_lookup.py new file mode 100644 index 0000000..7c576d7 --- /dev/null +++ b/python/spaces/spaces_lookup.py @@ -0,0 +1,38 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +search_url = "https://api.x.com/2/spaces" + +# Optional params: host_ids,conversation_controls,created_at,creator_id,id,invited_user_ids,is_ticketed,lang,media_key,participants,scheduled_start,speaker_ids,started_at,state,title,updated_at +query_params = {'ids': 'SPACE_ID', 'space.fields': 'title,created_at', 'expansions': 'creator_id'} + + +def create_headers(bearer_token): + headers = { + "Authorization": "Bearer {}".format(bearer_token), + "User-Agent": "v2SpacesLookupPython" + } + return headers + + +def connect_to_endpoint(url, headers, params): + response = requests.request("GET", search_url, headers=headers, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception(response.status_code, response.text) + return response.json() + + +def main(): + headers = create_headers(bearer_token) + json_response = connect_to_endpoint(search_url, headers, query_params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/python/streams/filtered_stream.py b/python/streams/filtered_stream.py index cdb937e..88d578b 100644 --- a/python/streams/filtered_stream.py +++ b/python/streams/filtered_stream.py @@ -1,23 +1,9 @@ -""" -Filtered Stream - X API v2 -========================== -Endpoint: GET https://api.x.com/2/tweets/search/stream -Docs: https://developer.x.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream - -Authentication: Bearer Token (App-only) -Required env vars: BEARER_TOKEN - -This example demonstrates: -1. Getting existing rules -2. Deleting all existing rules -3. Setting new rules -4. Connecting to the stream -""" - import requests import os import json +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") @@ -25,6 +11,7 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ + r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2FilteredStreamPython" return r @@ -63,7 +50,7 @@ def delete_all_rules(rules): def set_rules(delete): - # Adjust rules as needed + # You can adjust the rules if needed sample_rules = [ {"value": "dog has:images", "tag": "dog pictures"}, {"value": "cat has:images -grumpy", "tag": "cat pictures"}, diff --git a/python/streams/sampled-stream.py b/python/streams/sampled-stream.py new file mode 100644 index 0000000..ef0eb9d --- /dev/null +++ b/python/streams/sampled-stream.py @@ -0,0 +1,48 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + return "https://api.x.com/2/tweets/sample/stream" + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2SampledStreamPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth, stream=True) + print(response.status_code) + for response_line in response.iter_lines(): + if response_line: + json_response = json.loads(response_line) + print(json.dumps(json_response, indent=4, sort_keys=True)) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + + +def main(): + url = create_url() + timeout = 0 + while True: + connect_to_endpoint(url) + timeout += 1 + + +if __name__ == "__main__": + main() diff --git a/python/timelines/reverse-chron-home-timeline.py b/python/timelines/reverse-chron-home-timeline.py new file mode 100644 index 0000000..7b09c66 --- /dev/null +++ b/python/timelines/reverse-chron-home-timeline.py @@ -0,0 +1,112 @@ +import base64 +import hashlib +import os +import re +import json +import requests +from requests.auth import AuthBase, HTTPBasicAuth +from requests_oauthlib import OAuth2Session + +# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = os.environ.get("CLIENT_ID") + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = os.environ.get("CLIENT_SECRET") + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Set the scopes +scopes = ["tweet.read", "users.read", "offline.access"] + +# Create a code verifier +code_verifier = base64.urlsafe_b64encode(os.urandom(30)).decode("utf-8") +code_verifier = re.sub("[^a-zA-Z0-9]+", "", code_verifier) + +# Create a code challenge +code_challenge = hashlib.sha256(code_verifier.encode("utf-8")).digest() +code_challenge = base64.urlsafe_b64encode(code_challenge).decode("utf-8") +code_challenge = code_challenge.replace("=", "") + +# Start an OAuth 2.0 session +oauth = OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scopes) + +# Create an authorize URL +auth_url = "https://twitter.com/i/oauth2/authorize" +authorization_url, state = oauth.authorization_url( + auth_url, code_challenge=code_challenge, code_challenge_method="S256" +) + +# Visit the URL to authorize your App to make requests on behalf of a user +print( + "Visit the following URL to authorize your App on behalf of your Twitter handle in a browser:" +) +print(authorization_url) + +# Paste in your authorize URL to complete the request +authorization_response = input( + "Paste in the full URL after you've authorized your App:\n" +) + +# Fetch your access token +token_url = "https://api.x.com/2/oauth2/token" + +# The following line of code will only work if you are using a type of App that is a public client +auth = False + +# If you are using a confidential client you will need to pass in basic encoding of your client ID and client secret. + +# Please remove the comment on the following line if you are using a type of App that is a confidential client +# auth = HTTPBasicAuth(client_id, client_secret) + +token = oauth.fetch_token( + token_url=token_url, + authorization_response=authorization_response, + auth=auth, + client_id=client_id, + include_client_id=True, + code_verifier=code_verifier, +) + +# Your access token +access = token["access_token"] + +# Make a request to the users/me endpoint to get your user ID +user_me = requests.request( + "GET", + "https://api.x.com/2/users/me", + headers={"Authorization": "Bearer {}".format(access)}, +).json() + +# +# +# Now that we have user authorization, let's look up their home timeline. +# +# + +# Set the user. This defaults to the ID of the authorizing user. +user_id = user_me["data"]["id"] + +# Set the url. +url = "https://api.x.com/2/users/{}/timelines/reverse_chronological".format(user_id) + +headers = { + "Authorization": "Bearer {}".format(access), + "User-Agent": "ReverseChronSampleCode", +} +response = requests.request("GET", url, headers=headers) +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/timelines/user_mentions.py b/python/timelines/user_mentions.py index 2993206..4b9aca8 100644 --- a/python/timelines/user_mentions.py +++ b/python/timelines/user_mentions.py @@ -1,27 +1,26 @@ -""" -User Mentions Timeline - X API v2 -================================= -Endpoint: GET https://api.x.com/2/users/:id/mentions -Docs: https://developer.x.com/en/docs/twitter-api/tweets/timelines/api-reference/get-users-id-mentions - -Authentication: Bearer Token (App-only) or OAuth (User Context) -Required env vars: BEARER_TOKEN -""" - import requests import os import json +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' bearer_token = os.environ.get("BEARER_TOKEN") def create_url(): - # Replace with the user ID you want to get mentions for - user_id = "2244994945" + # Replace with user ID below + user_id = 2244994945 return "https://api.x.com/2/users/{}/mentions".format(user_id) def get_params(): + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld return {"tweet.fields": "created_at"} @@ -29,6 +28,7 @@ def bearer_oauth(r): """ Method required by bearer token authentication. """ + r.headers["Authorization"] = f"Bearer {bearer_token}" r.headers["User-Agent"] = "v2UserMentionsPython" return r @@ -38,7 +38,11 @@ def connect_to_endpoint(url, params): response = requests.request("GET", url, auth=bearer_oauth, params=params) print(response.status_code) if response.status_code != 200: - raise Exception(response.status_code, response.text) + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) return response.json() @@ -51,3 +55,4 @@ def main(): if __name__ == "__main__": main() + \ No newline at end of file diff --git a/python/timelines/user_tweets.py b/python/timelines/user_tweets.py new file mode 100644 index 0000000..8f547ea --- /dev/null +++ b/python/timelines/user_tweets.py @@ -0,0 +1,57 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with user ID below + user_id = 2244994945 + return "https://api.x.com/2/users/{}/tweets".format(user_id) + + +def get_params(): + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + return {"tweet.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2UserTweetsPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/usage/get_usage_tweets.py b/python/usage/get_usage_tweets.py new file mode 100644 index 0000000..23ad0d8 --- /dev/null +++ b/python/usage/get_usage_tweets.py @@ -0,0 +1,38 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2UsageTweetsPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = "https://api.x.com/2/usage/tweets" + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/users/block_a_user.py b/python/users/block_a_user.py new file mode 100644 index 0000000..2523aa6 --- /dev/null +++ b/python/users/block_a_user.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace id-to-block with the user id you wish to block. +payload = {"target_user_id": "id-to-block"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/blocking".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/users/followers_lookup.py b/python/users/followers_lookup.py new file mode 100644 index 0000000..ea51170 --- /dev/null +++ b/python/users/followers_lookup.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with user ID below + user_id = 2244994945 + return "https://api.x.com/2/users/{}/followers".format(user_id) + + +def get_params(): + return {"user.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FollowersLookupPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/users/following_lookup.py b/python/users/following_lookup.py new file mode 100644 index 0000000..be136e5 --- /dev/null +++ b/python/users/following_lookup.py @@ -0,0 +1,50 @@ +import requests +import os +import json + +# To set your environment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Replace with user ID below + user_id = 2244994945 + return "https://api.x.com/2/users/{}/following".format(user_id) + + +def get_params(): + return {"user.fields": "created_at"} + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2FollowingLookupPython" + return r + + +def connect_to_endpoint(url, params): + response = requests.request("GET", url, auth=bearer_oauth, params=params) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + params = get_params() + json_response = connect_to_endpoint(url, params) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/users/get_users_me_user_context.py b/python/users/get_users_me_user_context.py new file mode 100644 index 0000000..95cdafa --- /dev/null +++ b/python/users/get_users_me_user_context.py @@ -0,0 +1,73 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# User fields are adjustable, options include: +# created_at, description, entities, id, location, name, +# pinned_tweet_id, profile_image_url, protected, +# public_metrics, url, username, verified, and withheld +fields = "created_at,description" +params = {"user.fields": fields} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# # Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +response = oauth.get("https://api.x.com/2/users/me", params=params) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +json_response = response.json() + +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/users/get_users_with_bearer_token.py b/python/users/get_users_with_bearer_token.py new file mode 100644 index 0000000..4bc7c91 --- /dev/null +++ b/python/users/get_users_with_bearer_token.py @@ -0,0 +1,52 @@ +import requests +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'BEARER_TOKEN'='' +bearer_token = os.environ.get("BEARER_TOKEN") + + +def create_url(): + # Specify the usernames that you want to lookup below + # You can enter up to 100 comma-separated values. + usernames = "usernames=TwitterDev,TwitterAPI" + user_fields = "user.fields=description,created_at" + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + url = "https://api.x.com/2/users/by?{}&{}".format(usernames, user_fields) + return url + + +def bearer_oauth(r): + """ + Method required by bearer token authentication. + """ + + r.headers["Authorization"] = f"Bearer {bearer_token}" + r.headers["User-Agent"] = "v2UserLookupPython" + return r + + +def connect_to_endpoint(url): + response = requests.request("GET", url, auth=bearer_oauth,) + print(response.status_code) + if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text + ) + ) + return response.json() + + +def main(): + url = create_url() + json_response = connect_to_endpoint(url) + print(json.dumps(json_response, indent=4, sort_keys=True)) + + +if __name__ == "__main__": + main() diff --git a/python/users/get_users_with_user_context.py b/python/users/get_users_with_user_context.py new file mode 100644 index 0000000..295e285 --- /dev/null +++ b/python/users/get_users_with_user_context.py @@ -0,0 +1,75 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# User fields are adjustable, options include: +# created_at, description, entities, id, location, name, +# pinned_tweet_id, profile_image_url, protected, +# public_metrics, url, username, verified, and withheld +fields = "created_at,description" +params = {"usernames": "TwitterDev,TwitterAPI", "user.fields": fields} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# # Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +response = oauth.get( + "https://api.x.com/2/users/by", params=params +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +json_response = response.json() + +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/users/lookup_blocks.py b/python/users/lookup_blocks.py new file mode 100644 index 0000000..623c13a --- /dev/null +++ b/python/users/lookup_blocks.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +params = {"user.fields": "created_at,description"} +# User fields are adjustable, options include: +# created_at, description, entities, id, location, name, +# pinned_tweet_id, profile_image_url, protected, +# public_metrics, url, username, verified, and withheld + +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +response = oauth.get( + "https://api.x.com/2/users/{}/blocking".format(id), params=params +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/users/lookup_mutes.py b/python/users/lookup_mutes.py new file mode 100644 index 0000000..298bb58 --- /dev/null +++ b/python/users/lookup_mutes.py @@ -0,0 +1,79 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# To set your enviornment variables in your terminal run the following line: +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +params = {"user.fields": "created_at,description"} + + +# User fields are adjustable, options include: +# created_at, description, entities, id, location, name, +# pinned_tweet_id, profile_image_url, protected, +# public_metrics, url, username, verified, and withheld + +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +response = oauth.get( + "https://api.x.com/2/users/{}/muting".format(id),params=params +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format( + response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) \ No newline at end of file diff --git a/python/users/mute_a_user.py b/python/users/mute_a_user.py new file mode 100644 index 0000000..7a664a7 --- /dev/null +++ b/python/users/mute_a_user.py @@ -0,0 +1,77 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to replace id-to-mute with the user id you wish to mute. +payload = {"target_user_id": "id-to-mute"} + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.post( + "https://api.x.com/2/users/{}/muting".format(id), json=payload +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/python/users/unblock_a_user.py b/python/users/unblock_a_user.py new file mode 100644 index 0000000..62ea052 --- /dev/null +++ b/python/users/unblock_a_user.py @@ -0,0 +1,81 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +source_user_id = "your-user-id" + +# Be sure to add replace id-to-unblock with the id of the user you wish to unblock. +# You can find a user ID by using the user lookup endpoint +target_user_id = "id-to-unblock" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/blocking/{}".format(id, target_user_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) + +# Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/python/users/unmute_a_user.py b/python/users/unmute_a_user.py new file mode 100644 index 0000000..268e545 --- /dev/null +++ b/python/users/unmute_a_user.py @@ -0,0 +1,79 @@ +from requests_oauthlib import OAuth1Session +import os +import json + +# In your terminal please set your environment variables by running the following lines of code. +# export 'CONSUMER_KEY'='' +# export 'CONSUMER_SECRET'='' + +consumer_key = os.environ.get("CONSUMER_KEY") +consumer_secret = os.environ.get("CONSUMER_SECRET") + + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +source_user_id = "your-user-id" + +# Be sure to add replace id-to-unmute with the id of the user you wish to unmute. +# You can find a user ID by using the user lookup endpoint +target_user_id = "id-to-unmute" + + +# Get request token +request_token_url = "https://api.x.com/oauth/request_token" +oauth = OAuth1Session(consumer_key, client_secret=consumer_secret) + +try: + fetch_response = oauth.fetch_request_token(request_token_url) +except ValueError: + print( + "There may have been an issue with the consumer_key or consumer_secret you entered." + ) + +resource_owner_key = fetch_response.get("oauth_token") +resource_owner_secret = fetch_response.get("oauth_token_secret") +print("Got OAuth token: %s" % resource_owner_key) + +# Get authorization +base_authorization_url = "https://api.x.com/oauth/authorize" +authorization_url = oauth.authorization_url(base_authorization_url) +print("Please go here and authorize: %s" % authorization_url) +verifier = input("Paste the PIN here: ") + +# Get the access token +access_token_url = "https://api.x.com/oauth/access_token" +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=resource_owner_key, + resource_owner_secret=resource_owner_secret, + verifier=verifier, +) +oauth_tokens = oauth.fetch_access_token(access_token_url) + +access_token = oauth_tokens["oauth_token"] +access_token_secret = oauth_tokens["oauth_token_secret"] + +# Make the request +oauth = OAuth1Session( + consumer_key, + client_secret=consumer_secret, + resource_owner_key=access_token, + resource_owner_secret=access_token_secret, +) + +# Making the request +response = oauth.delete( + "https://api.x.com/2/users/{}/muting/{}".format(id, target_user_id) +) + +if response.status_code != 200: + raise Exception( + "Request returned an error: {} {}".format(response.status_code, response.text) + ) + +print("Response code: {}".format(response.status_code)) + +# Saving the response as JSON +json_response = response.json() +print(json.dumps(json_response, indent=4, sort_keys=True)) diff --git a/r/posts/full-archive-search.r b/r/posts/full-archive-search.r new file mode 100644 index 0000000..666953f --- /dev/null +++ b/r/posts/full-archive-search.r @@ -0,0 +1,26 @@ +library(httr) + +# Replace the bearer token below with +bearer_token = "" + +headers = c( + `Authorization` = sprintf('Bearer %s', bearer_token) +) + +params = list( + `query` = 'from:twitterdev lang:en', + `max_results` = '10', + `tweet.fields` = 'created_at,lang,context_annotations' +) + +response <- httr::GET(url = 'https://api.x.com/2/tweets/search/all', httr::add_headers(.headers=headers), query = params) + +fas_body <- + content( + response, + as = 'parsed', + type = 'application/json', + simplifyDataFrame = TRUE + ) + +View(fas_body$data) \ No newline at end of file diff --git a/r/posts/full_archive_tweet_counts.r b/r/posts/full_archive_tweet_counts.r new file mode 100644 index 0000000..0c82bde --- /dev/null +++ b/r/posts/full_archive_tweet_counts.r @@ -0,0 +1,25 @@ +library(httr) + +# Replace the bearer token below with +bearer_token = "" + +headers = c( + `Authorization` = sprintf('Bearer %s', bearer_token) +) + +params = list( + `query` = 'from:twitterdev', + `granularity` = 'day' +) + +response <- httr::GET(url = 'https://api.x.com/2/tweets/counts/all', httr::add_headers(.headers=headers), query = params) + +body <- + content( + response, + as = 'parsed', + type = 'application/json', + simplifyDataFrame = TRUE + ) + +View(body$data) \ No newline at end of file diff --git a/r/posts/recent-search.r b/r/posts/recent-search.r new file mode 100644 index 0000000..d01c9b3 --- /dev/null +++ b/r/posts/recent-search.r @@ -0,0 +1,28 @@ +require(httr) + + +bearer_token = "" +headers = c( + `Authorization` = sprintf('Bearer %s', bearer_token) +) + + +params = list( + `query` = 'from:TwitterDev', + `max_results` = '10', + `tweet.fields` = 'created_at,lang,conversation_id' +) + + +response <- httr::GET(url = 'https://api.x.com/2/tweets/search/recent', httr::add_headers(.headers=headers), query = params) + + +recent_search_body <- + content( + response, + as = 'parsed', + type = 'application/json', + simplifyDataFrame = TRUE + ) + +View(recent_search_body$data) diff --git a/r/posts/recent_tweet_counts.r b/r/posts/recent_tweet_counts.r new file mode 100644 index 0000000..179f1bc --- /dev/null +++ b/r/posts/recent_tweet_counts.r @@ -0,0 +1,25 @@ +library(httr) + +# Replace the bearer token below with +bearer_token = "" + +headers = c( + `Authorization` = sprintf('Bearer %s', bearer_token) +) + +params = list( + `query` = 'from:twitterdev', + `granularity` = 'day' +) + +response <- httr::GET(url = 'https://api.x.com/2/tweets/counts/recent', httr::add_headers(.headers=headers), query = params) + +body <- + content( + response, + as = 'parsed', + type = 'application/json', + simplifyDataFrame = TRUE + ) + +View(body$data) \ No newline at end of file diff --git a/r/users/get_users_with_bearer_token.r b/r/users/get_users_with_bearer_token.r new file mode 100644 index 0000000..e0582a3 --- /dev/null +++ b/r/users/get_users_with_bearer_token.r @@ -0,0 +1,20 @@ +require(httr) + +bearer_token <- "" + +headers <- c(`Authorization` = sprintf('Bearer %s', bearer_token)) + +params <- list(`user.fields` = 'description') + +handle <- 'TwitterDev' + +url_handle <- + sprintf('https://api.x.com/2/users/by?usernames=%s', handle) + +response <- + httr::GET(url = url_handle, + httr::add_headers(.headers = headers), + query = params) + +obj <- httr::content(res, as = "text") +print(obj) diff --git a/ruby/Gemfile b/ruby/Gemfile index 5d49520..79e382d 100644 --- a/ruby/Gemfile +++ b/ruby/Gemfile @@ -1,9 +1,3 @@ -# X API v2 Ruby Examples - Dependencies - source 'https://rubygems.org' - -# HTTP client gem 'typhoeus', '~> 1.4' - -# OAuth 1.0a authentication gem 'oauth', '~> 1.1' diff --git a/ruby/bookmarks/bookmarks_lookup.rb b/ruby/bookmarks/bookmarks_lookup.rb new file mode 100644 index 0000000..e529019 --- /dev/null +++ b/ruby/bookmarks/bookmarks_lookup.rb @@ -0,0 +1,110 @@ +require 'json' +require 'typhoeus' +require 'twitter_oauth2' + +# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = ENV["CLIENT_ID"] + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = ENV["CLIENT_SECRET"] + + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Start an OAuth 2.0 session with a public client +client = TwitterOAuth2::Client.new( + identifier: "#{client_id}", + redirect_uri: "#{redirect_uri}" +) + +# Start an OAuth 2.0 session with a confidential client + +# Remove the comment on the following lines if you are using a confidential client +# client = TwitterOAuth2::Client.new( +# identifier: "#{client_id}", +# secret: "#{client_secret}", +# redirect_uri: "#{redirect_uri}" +# ) + +# Create your authorize url +authorization_url = client.authorization_uri( + # Update scopes if needed + scope: [ + :'users.read', + :'tweet.read', + :'bookmark.read', + :'offline.access' + ] +) + +# Set code verifier and state +code_verifier = client.code_verifier +state = client.state + +# Visit the URL to authorize your App to make requests on behalf of a user +print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' +puts authorization_url +`open "#{authorization_url}"` + +print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush + +# Fetch your access token +full_text = gets.chop +new_code = full_text.split("code=") +code = new_code[1] +client.authorization_code = code + +# Your access token +token_response = client.access_token! code_verifier + +# Make a request to the users/me endpoint to get your user ID +def users_me(url, token_response) + options = { + method: 'get', + headers: { + "User-Agent": "BookmarksSampleCode", + "Authorization": "Bearer #{token_response}" + }, + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +url = "https://api.x.com/2/users/me" +me_response = users_me(url, token_response) + +json_s = JSON.parse(me_response.body) +user_id = json_s["data"]["id"] + +# Make a request to the bookmarks url +bookmarks_url = "https://api.x.com/2/users/#{user_id}/bookmarks" + +def bookmarked_tweets(bookmarks_url, token_response) + options = { + method: 'get', + headers: { + "User-Agent": "BookmarksSampleCode", + "Authorization": "Bearer #{token_response}" + } + } + + request = Typhoeus::Request.new(bookmarks_url, options) + response = request.run + + return response +end + +response = bookmarked_tweets(bookmarks_url, token_response) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/List-Tweets.rb b/ruby/lists/List-Tweets.rb new file mode 100644 index 0000000..5d2c2ee --- /dev/null +++ b/ruby/lists/List-Tweets.rb @@ -0,0 +1,44 @@ +# This script uses your bearer token to authenticate and retrieve the specified Tweet objects (by List ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace list-id with any List ID +id = "list-id" +url = "https://api.x.com/2/lists/#{id}/tweets" + + +params = { + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + "tweet.fields": "lang,author_id", +} + +def list_tweets(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListTweetsLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = list_tweets(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/Pinned-List.rb b/ruby/lists/Pinned-List.rb new file mode 100644 index 0000000..e1e7645 --- /dev/null +++ b/ruby/lists/Pinned-List.rb @@ -0,0 +1,89 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +url = "https://api.x.com/2/users/#{id}/pinned_lists" + +@params = { + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + "list.fields": "created_at,follower_count" +} + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def pin_list(url, oauth_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2pinListLookupRuby", + "content-type": "application/json" + }, + params: @params + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = pin_list(url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/add_member.rb b/ruby/lists/add_member.rb new file mode 100644 index 0000000..8c5888b --- /dev/null +++ b/ruby/lists/add_member.rb @@ -0,0 +1,84 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-list-id with your own list ID or one of an authenticating user +id = "your-list-id" + +member_url = "https://api.x.com/2/lists/#{id}/members" + +# Be sure to replace user-id-to-add with the user id you wish to add. +@user_id = { "user_id": "user-id-to-add" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def add_member(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2addMemberRuby", + "content-type": "application/json" + }, + body: JSON.dump(@user_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = add_member(member_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/create_a_list.rb b/ruby/lists/create_a_list.rb new file mode 100644 index 0000000..96e3dc0 --- /dev/null +++ b/ruby/lists/create_a_list.rb @@ -0,0 +1,86 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + + +create_list_url = "https://api.x.com/2/lists" + +# Be sure to add replace name-of-list with the name you wish to call the list. +# description and private keys are optional +@json_payload = { "name": "name-of-list", +"description": "description-of-list", +"private": false} + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def create_list(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2createListRuby", + "content-type": "application/json" + }, + body: JSON.dump(@json_payload) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = create_list(create_list_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/delete_a_list.rb b/ruby/lists/delete_a_list.rb new file mode 100644 index 0000000..af8cef2 --- /dev/null +++ b/ruby/lists/delete_a_list.rb @@ -0,0 +1,83 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-list-id with the id of the list you wish to delete. The authenticated user must own the list in order to delete + +id = "your-list-id" + +delete_list_url = "https://api.x.com/2/lists/#{id}" + + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def delete_list(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2deleteListRuby", + "content-type": "application/json" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = delete_list(delete_list_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/follow_list.rb b/ruby/lists/follow_list.rb new file mode 100644 index 0000000..0e5efe9 --- /dev/null +++ b/ruby/lists/follow_list.rb @@ -0,0 +1,85 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +following_url = "https://api.x.com/2/users/#{id}/followed_lists" + +# Be sure to add replace list-id-to-follow with the list id you wish to follow. +@list_id = { "list_id": "list-id-to-follow" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def follow_list(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2followListRuby", + "content-type": "application/json" + }, + body: JSON.dump(@list_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = follow_list(following_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/list-followers-lookup.rb b/ruby/lists/list-followers-lookup.rb new file mode 100644 index 0000000..70538e0 --- /dev/null +++ b/ruby/lists/list-followers-lookup.rb @@ -0,0 +1,41 @@ +# This script uses your bearer token to authenticate and retrieve followers of a List specified by List ID + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace list-id with any List ID +id = "list-id" +url = "https://api.x.com/2/lists/#{id}/followers" + + +params = { + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + "user.fields": "created_at,verified", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListFollowersLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/list-lookup-by-id.rb b/ruby/lists/list-lookup-by-id.rb new file mode 100644 index 0000000..4aaaba3 --- /dev/null +++ b/ruby/lists/list-lookup-by-id.rb @@ -0,0 +1,40 @@ +# This script uses your bearer token to authenticate and retrieve the specified List objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace list-id with any List ID +id = "list-id" +url = "https://api.x.com/2/lists/#{id}" + + +params = { + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + "list.fields": "created_at,follower_count", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/list-member-lookup.rb b/ruby/lists/list-member-lookup.rb new file mode 100644 index 0000000..f00cc9c --- /dev/null +++ b/ruby/lists/list-member-lookup.rb @@ -0,0 +1,41 @@ +# This script uses your bearer token to authenticate and retrieve members of a List specified by List ID + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace list-id with any List ID +id = "list-id" +url = "https://api.x.com/2/lists/#{id}/members" + + +params = { + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + "user.fields": "created_at,verified", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListMembersLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/pin_list.rb b/ruby/lists/pin_list.rb new file mode 100644 index 0000000..c32f5db --- /dev/null +++ b/ruby/lists/pin_list.rb @@ -0,0 +1,85 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +pin_url = "https://api.x.com/2/users/#{id}/pinned_lists" + +# Be sure to add replace list-id-to-pin with the list id you wish to pin. +@list_id = { "list_id": "list-id-to-pin" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def pin_list(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2pinListRuby", + "content-type": "application/json" + }, + body: JSON.dump(@list_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = pin_list(pin_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/remove_member.rb b/ruby/lists/remove_member.rb new file mode 100644 index 0000000..3c51687 --- /dev/null +++ b/ruby/lists/remove_member.rb @@ -0,0 +1,83 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-list-id with your own list ID or one of an authenticating user +id = "your-list-id" + +# Be sure to replace user-id-to-remove with the user id you wish to remove. +user_id = "user-id-to-remove" + +member_url = "https://api.x.com/2/lists/#{id}/members/#{user_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def remove_member(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2removeMemberRuby", + "content-type": "application/json" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = remove_member(member_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/unfollow_list.rb b/ruby/lists/unfollow_list.rb new file mode 100644 index 0000000..adf937b --- /dev/null +++ b/ruby/lists/unfollow_list.rb @@ -0,0 +1,81 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-unfollow with the user id of the user you wish to unfollow. +list_id = "list-id-to-unfollow" + +# Returns a user object for one or more users specified by the requested usernames +unfollow_url = "https://api.x.com/2/users/#{id}/followed_lists/#{list_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def unfollow_list(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2unfollowListRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = unfollow_list(unfollow_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/unpin_list.rb b/ruby/lists/unpin_list.rb new file mode 100644 index 0000000..0524ac6 --- /dev/null +++ b/ruby/lists/unpin_list.rb @@ -0,0 +1,81 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# Be sure to add replace list-id-to-unpin with the user id of the user you wish to unpin. +list_id = "list-id-to-unpin" + +# Returns a user object for one or more users specified by the requested usernames +unpin_url = "https://api.x.com/2/users/#{id}/pinned_lists/#{list_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def unpin_list(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2unpinListRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = unpin_list(unpin_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/update_a_list.rb b/ruby/lists/update_a_list.rb new file mode 100644 index 0000000..b9c2a8f --- /dev/null +++ b/ruby/lists/update_a_list.rb @@ -0,0 +1,89 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to add replace update-name-of-list with the name you wish to call the list. +# name, description and private are all optional +@json_payload = { "name": "update-name-of-list-ruby", + "description": "update-description-of-list", + "private": false} + +# Be sure to replace your-list-id with the id of the list you wish to update. The authenticated user must own the list in order to update +id = "your-list-id" + +update_list_url = "https://api.x.com/2/lists/#{id}" + + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def update_list(url, oauth_params) + options = { + :method => :put, + headers: { + "User-Agent": "v2updateListRuby", + "content-type": "application/json" + }, + body: JSON.dump(@json_payload) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = update_list(update_list_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/user-list-followed.rb b/ruby/lists/user-list-followed.rb new file mode 100644 index 0000000..f8acd26 --- /dev/null +++ b/ruby/lists/user-list-followed.rb @@ -0,0 +1,40 @@ +# This script uses your bearer token to authenticate and retrieve the specified List objects (by user ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace user-id with any User ID +id = "user-id" +url = "https://api.x.com/2/users/#{id}/followed_lists" + + +params = { + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + "list.fields": "created_at,private", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2userMembershipsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/user-list-memberships.rb b/ruby/lists/user-list-memberships.rb new file mode 100644 index 0000000..373d2bd --- /dev/null +++ b/ruby/lists/user-list-memberships.rb @@ -0,0 +1,40 @@ +# This script uses your bearer token to authenticate and retrieve the specified List objects (by user ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace user-id with any User ID +id = "user-id" +url = "https://api.x.com/2/users/#{id}/list_memberships" + + +params = { + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + "list.fields": "created_at,private", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2userMembershipsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/lists/user-owned-list-lookup.rb b/ruby/lists/user-owned-list-lookup.rb new file mode 100644 index 0000000..c05936b --- /dev/null +++ b/ruby/lists/user-owned-list-lookup.rb @@ -0,0 +1,40 @@ +# This script uses your bearer token to authenticate and retrieve any user owned Lists specified by user ID + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + + # You can replace the ID with the User ID to see if they own any Lists. +id = "user-id" +url = "https://api.x.com/2/users/#{id}/owned_lists" + + +params = { + # List fields are adjustable, options include: + # created_at, description, owner_id, + # private, follower_count, member_count, + "list.fields": "created_at,follower_count", +} + +def lists(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2ListLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = lists(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/create_tweet.rb b/ruby/posts/create_tweet.rb new file mode 100644 index 0000000..9fb8c0e --- /dev/null +++ b/ruby/posts/create_tweet.rb @@ -0,0 +1,82 @@ +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + + +create_tweet_url = "https://api.x.com/2/tweets" + +# Be sure to add replace the text of the with the text you wish to Tweet. +# You can also add parameters to post polls, quote Tweets, Tweet with reply settings, and Tweet to Super Followers in addition to other features. +@json_payload = {"text": "Hello world!"} + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def create_tweet(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2CreateTweetRuby", + "content-type": "application/json" + }, + body: JSON.dump(@json_payload) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = create_tweet(create_tweet_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/delete_tweet.rb b/ruby/posts/delete_tweet.rb new file mode 100644 index 0000000..2a0ad3b --- /dev/null +++ b/ruby/posts/delete_tweet.rb @@ -0,0 +1,79 @@ +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-tweet-id with the id of the Tweet you wish to delete. +id = "your-tweet-id" + +delete_tweet_url = "https://api.x.com/2/tweets/#{id}" + + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def delete_tweet(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2DeleteTweetRuby", + "content-type": "application/json" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = delete_tweet(delete_tweet_url, oauth_params) diff --git a/ruby/posts/full-archive-search.rb b/ruby/posts/full-archive-search.rb new file mode 100644 index 0000000..854f04a --- /dev/null +++ b/ruby/posts/full-archive-search.rb @@ -0,0 +1,49 @@ +# This script uses your bearer token to authenticate and make a Search request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Full-archive Search API +search_url = "https://api.x.com/2/tweets/search/all" + +# Set the query value here. Value can be up to 512 characters +query = "from:Twitter OR from:TwitterDev OR from:DailyNasa" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-all +query_params = { + "query": query, # Required + "max_results": 10, + # "start_time": "2020-07-01T00:00:00Z", + # "end_time": "2020-07-02T18:00:00Z", + # "expansions": "attachments.poll_ids,attachments.media_keys,author_id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields": "description" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +def search_tweets(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2FullArchiveSearchRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = search_tweets(search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/full_archive_tweet_counts.rb b/ruby/posts/full_archive_tweet_counts.rb new file mode 100644 index 0000000..4e9c85c --- /dev/null +++ b/ruby/posts/full_archive_tweet_counts.rb @@ -0,0 +1,42 @@ +# This script uses your bearer token to authenticate and make a Search request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Full-archive Search API +search_url = "https://api.x.com/2/tweets/counts/all" + +# Set the query value here. Value can be up to 1024 characters +query = "from:TwitterDev" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-counts-all +query_params = { + "query": query, # Required + "start_time": "2021-01-01T00:00:00Z", + "granularity": "day" +} + +def get_tweet_counts(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2FullArchiveTweetCountsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_tweet_counts(search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/get_tweets_with_bearer_token.rb b/ruby/posts/get_tweets_with_bearer_token.rb new file mode 100644 index 0000000..8f95b47 --- /dev/null +++ b/ruby/posts/get_tweets_with_bearer_token.rb @@ -0,0 +1,45 @@ +# This script uses your bearer token to authenticate and retrieve the specified Tweet objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +tweet_lookup_url = "https://api.x.com/2/tweets" + +# Specify the Tweet IDs that you want to lookup below (to 100 per request) +tweet_ids = "1261326399320715264,1278347468690915330" + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference +params = { + "ids": tweet_ids, + # "expansions": "author_id,referenced_tweets.id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "name" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +def tweet_lookup(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2TweetLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = tweet_lookup(tweet_lookup_url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/get_tweets_with_user_context.rb b/ruby/posts/get_tweets_with_user_context.rb new file mode 100644 index 0000000..06aa9f5 --- /dev/null +++ b/ruby/posts/get_tweets_with_user_context.rb @@ -0,0 +1,91 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a Tweet lookup request (by IDs) with OAuth 1.0a authentication (user context) + +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Returns a Tweet object for one or more Tweets IDs as specified by the request +tweet_lookup_url = "https://api.x.com/2/tweets" + +# Specify the Tweet IDs that you want to lookup below (to 100 per request) +tweet_ids = "1261326399320715264,1278347468690915330" + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/tweets/lookup/api-reference +query_params = { + "ids": tweet_ids, + # "expansions": "author_id,referenced_tweets.id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "name" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + +def tweet_lookup(url, oauth_params, query_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2TweetLookupRuby" + }, + params: query_params + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = tweet_lookup(tweet_lookup_url, oauth_params, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/like_a_tweet.rb b/ruby/posts/like_a_tweet.rb new file mode 100644 index 0000000..d44c241 --- /dev/null +++ b/ruby/posts/like_a_tweet.rb @@ -0,0 +1,86 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" +likes_url = "https://api.x.com/2/users/#{id}/likes" + +# You can replace Tweet ID given with the Tweet ID you wish to like. +# You can find a Tweet ID by using the Tweet lookup endpoint +@tweet_id = { "tweet_id": "1354143047324299264" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_like(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2LikeTweetRuby", + "content-type": "application/json" + }, + body: JSON.dump(@tweet_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = user_like(likes_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/liked_tweets.rb b/ruby/posts/liked_tweets.rb new file mode 100644 index 0000000..4cc4e3a --- /dev/null +++ b/ruby/posts/liked_tweets.rb @@ -0,0 +1,45 @@ +# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" +url = "https://api.x.com/2/users/#{id}/liked_tweets" + + +params = { + # Tweet fields are adjustable. + # Options include: + # attachments, author_id, context_annotations, + # conversation_id, created_at, entities, geo, id, + # in_reply_to_user_id, lang, non_public_metrics, organic_metrics, + # possibly_sensitive, promoted_metrics, public_metrics, referenced_tweets, + # source, text, and withheld + "tweet.fields": "lang,author_id", +} + +def liked_tweets(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2LikedTweetsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = liked_tweets(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/liking_users.rb b/ruby/posts/liking_users.rb new file mode 100644 index 0000000..d879e6f --- /dev/null +++ b/ruby/posts/liking_users.rb @@ -0,0 +1,43 @@ +# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + + +# You can replace the ID given with the Tweet ID you wish to like. +# You can find an ID by using the Tweet lookup endpoint +id = "1354143047324299264" + +url = "https://api.x.com/2/tweets/#{id}/liking_users" + +params = { + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + "user.fields": "created_at,description", +} + +def liking_users(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2LikingUsersRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = liking_users(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/quote_tweets.rb b/ruby/posts/quote_tweets.rb new file mode 100644 index 0000000..77d1f9c --- /dev/null +++ b/ruby/posts/quote_tweets.rb @@ -0,0 +1,44 @@ +# This script uses your bearer token to authenticate and make a request to the Quote Tweets endpoint. +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Quote Tweets endpoint. +endpoint_url = "https://api.x.com/2/tweets/:id/quote_tweets" + +# Specify the Tweet ID for this request. +id = 20 + +# Add or remove parameters below to adjust the query and response fields within the payload +# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ +query_params = { + "max_results" => 100, + "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", + "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields" => "description" +} + +def get_quote_tweets(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent" => "v2RubyExampleCode", + "Authorization" => "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +endpoint_url = endpoint_url.gsub(':id',id.to_s()) + +response = get_quote_tweets(endpoint_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/recent_search.rb b/ruby/posts/recent_search.rb new file mode 100644 index 0000000..ada35fb --- /dev/null +++ b/ruby/posts/recent_search.rb @@ -0,0 +1,49 @@ +# This script uses your bearer token to authenticate and make a Search request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Recent Search API +search_url = "https://api.x.com/2/tweets/search/recent" + +# Set the query value here. Value can be up to 512 characters +query = "from:Twitter OR from:TwitterDev OR from:DailyNasa" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent +query_params = { + "query": query, # Required + "max_results": 10, + # "start_time": "2020-07-01T00:00:00Z", + # "end_time": "2020-07-02T18:00:00Z", + # "expansions": "attachments.poll_ids,attachments.media_keys,author_id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields": "description" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +def search_tweets(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2RecentSearchRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = search_tweets(search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/recent_tweet_counts.rb b/ruby/posts/recent_tweet_counts.rb new file mode 100644 index 0000000..beff26e --- /dev/null +++ b/ruby/posts/recent_tweet_counts.rb @@ -0,0 +1,41 @@ +# This script uses your bearer token to authenticate and make a Search request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Recent Search API +search_url = "https://api.x.com/2/tweets/counts/recent" + +# Set the query value here. Value can be up to 512 characters +query = "from:TwitterDev" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-counts-recent +query_params = { + "query": query, # Required + "granularity": "day" +} + +def get_tweet_counts(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2RecentTweetCountsRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_tweet_counts(search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/retweet_a_tweet.rb b/ruby/posts/retweet_a_tweet.rb new file mode 100644 index 0000000..f02586a --- /dev/null +++ b/ruby/posts/retweet_a_tweet.rb @@ -0,0 +1,86 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to add replace id of the user you wish to retweet on behalf of. +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" +retweets_url = "https://api.x.com/2/users/#{id}/retweets" + +# Be sure to replace tweet-id with your the Tweet ID you want to retweet +# You can find a Tweet ID by using the Tweet lookup endpoint +@tweet_id = { "tweet_id": "1412865600439738368" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_retweet(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2retweetUserRuby", + "content-type": "application/json" + }, + body: JSON.dump(@tweet_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = user_retweet(retweets_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/retweeted_by.rb b/ruby/posts/retweeted_by.rb new file mode 100644 index 0000000..14d1b4d --- /dev/null +++ b/ruby/posts/retweeted_by.rb @@ -0,0 +1,43 @@ +# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + + +# You can replace the ID given with the Tweet ID you wish to lookup Retweeting users for +# You can find an ID by using the Tweet lookup endpoint +id = "1412865600439738368" + +url = "https://api.x.com/2/tweets/#{id}/retweeted_by" + +params = { + # User fields are adjustable, options include: + # created_at, description, entities, id, location, name, + # pinned_tweet_id, profile_image_url, protected, + # public_metrics, url, username, verified, and withheld + "user.fields": "created_at,description", +} + +def retweeted_by_users(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2RetweetedbyUsersRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = retweeted_by_users(url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/undo_a_retweet.rb b/ruby/posts/undo_a_retweet.rb new file mode 100644 index 0000000..33e14a3 --- /dev/null +++ b/ruby/posts/undo_a_retweet.rb @@ -0,0 +1,84 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) + +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace the given Tweet ID with your the Tweet ID you want to Retweet +# You can find a Tweet ID by using the Tweet lookup endpoint +source_tweet_id = "1412865600439738368" + +# Returns a user object for one or more users specified by the requested usernames +user_unretweet_url = "https://api.x.com/2/users/#{id}/retweets/#{source_tweet_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_unretweet(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2UndoRetweetUserRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = user_unretweet(user_unretweet_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/posts/unlike_a_tweet.rb b/ruby/posts/unlike_a_tweet.rb new file mode 100644 index 0000000..f4cb59c --- /dev/null +++ b/ruby/posts/unlike_a_tweet.rb @@ -0,0 +1,84 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) + +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticated user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +# You can replace Tweet ID given with the Tweet ID you wish to like. +# You can find a Tweet ID by using the Tweet lookup endpoint +tweet_id = "1354143047324299264" + +# Returns a user object for one or more users specified by the requested usernames +tweet_unlike_url = "https://api.x.com/2/users/#{id}/likes/#{tweet_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def tweet_unlike(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2UnlikeTweetRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = tweet_unlike(tweet_unlike_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/spaces/search_spaces.rb b/ruby/spaces/search_spaces.rb new file mode 100644 index 0000000..2980ad7 --- /dev/null +++ b/ruby/spaces/search_spaces.rb @@ -0,0 +1,42 @@ +# This script uses your bearer token to authenticate and make a Spaces lookup request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on macOS, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL +spaces_search_url = "https://api.x.com/2/spaces/search" + +# Replace this value with your search term +query = "NBA" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/spaces/search/api-reference +query_params = { + "query": query, # Required + "space.fields": 'title,created_at', + 'expansions': 'creator_id' +} + +def get_space(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2SpacesSearchRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_space(spaces_search_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/spaces/spaces_lookup.rb b/ruby/spaces/spaces_lookup.rb new file mode 100644 index 0000000..2c900cb --- /dev/null +++ b/ruby/spaces/spaces_lookup.rb @@ -0,0 +1,42 @@ +# This script uses your bearer token to authenticate and make a Spaces lookup request + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on macOS, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for Spaces lookup +spaces_lookup_url = "https://api.x.com/2/spaces" + +# Replace SPACE_ID with the ID of a Space +id = "SPACE_ID" + +# Add or remove parameters below to adjust the query and response fields within the payload +# See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference +query_params = { + "ids": id, # Required + "space.fields": 'title,created_at', + 'expansions': 'creator_id' +} + +def get_space(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent": "v2SpacesLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = get_space(spaces_lookup, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/streams/filtered_stream.rb b/ruby/streams/filtered_stream.rb new file mode 100644 index 0000000..d1cf889 --- /dev/null +++ b/ruby/streams/filtered_stream.rb @@ -0,0 +1,144 @@ +# This script contains methods to add, remove, and retrieve rules from your stream. +# It will also connect to the stream endpoint and begin outputting data. +# Run as-is, the script gives you the option to replace existing rules with new ones and begin streaming data + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +@bearer_token = ENV["BEARER_TOKEN"] + +@stream_url = "https://api.x.com/2/tweets/search/stream" +@rules_url = "https://api.x.com/2/tweets/search/stream/rules" + +@sample_rules = [ + { 'value': 'dog has:images', 'tag': 'dog pictures' }, + { 'value': 'cat has:images -grumpy', 'tag': 'cat pictures' }, +] + +# Add or remove values from the optional parameters below. Full list of parameters can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/api-reference/get-tweets-search-stream +params = { + "expansions": "attachments.poll_ids,attachments.media_keys,author_id,entities.mentions.username,geo.place_id,in_reply_to_user_id,referenced_tweets.id,referenced_tweets.id.author_id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "description", + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +# Get request to rules endpoint. Returns list of of active rules from your stream +def get_all_rules + @options = { + headers: { + "User-Agent": "v2FilteredStreamRuby", + "Authorization": "Bearer #{@bearer_token}" + } + } + + @response = Typhoeus.get(@rules_url, @options) + + raise "An error occurred while retrieving active rules from your stream: #{@response.body}" unless @response.success? + + @body = JSON.parse(@response.body) +end + +# Post request to add rules to your stream +def set_rules(rules) + return if rules.nil? + + @payload = { + add: rules + } + + @options = { + headers: { + "User-Agent": "v2FilteredStreamRuby", + "Authorization": "Bearer #{@bearer_token}", + "Content-type": "application/json" + }, + body: JSON.dump(@payload) + } + + @response = Typhoeus.post(@rules_url, @options) + raise "An error occurred while adding rules: #{@response.status_message}" unless @response.success? +end + +# Post request with a delete body to remove rules from your stream +def delete_all_rules(rules) + return if rules.nil? + + @ids = rules['data'].map { |rule| rule["id"] } + @payload = { + delete: { + ids: @ids + } + } + + @options = { + headers: { + "User-Agent": "v2FilteredStreamRuby", + "Authorization": "Bearer #{@bearer_token}", + "Content-type": "application/json" + }, + body: JSON.dump(@payload) + } + + @response = Typhoeus.post(@rules_url, @options) + + raise "An error occurred while deleting your rules: #{@response.status_message}" unless @response.success? +end + +# Helper method that gets active rules and prompts to delete (y/n), then adds new rules set in line 17 (@sample_rules) +def setup_rules + # Gets the complete list of rules currently applied to the stream + @rules = get_all_rules + puts "Found existing rules on the stream:\n #{@rules}\n" + + puts "Do you want to delete existing rules and replace with new rules? [y/n]" + answer = gets.chomp + if answer == "y" + # Delete all rules + delete_all_rules(@rules) + else + puts "Keeping existing rules and adding new ones." + end + + # Add rules to the stream + set_rules(@sample_rules) +end + +# Connects to the stream and returns data (Tweet payloads) in chunks +def stream_connect(params) + @options = { + timeout: 20, + method: 'get', + headers: { + "User-Agent": "v2FilteredStreamRuby", + "Authorization": "Bearer #{@bearer_token}" + }, + params: params + } + + @request = Typhoeus::Request.new(@stream_url, @options) + @request.on_body do |chunk| + puts chunk + end + @request.run +end + +# Comment this line if you already setup rules and want to keep them +setup_rules + +# Listen to the stream. +# This reconnection logic will attempt to reconnect when a disconnection is detected. +# To avoid rate limites, this logic implements exponential backoff, so the wait time +# will increase if the client cannot reconnect to the stream. +timeout = 0 +while true + stream_connect(params) + sleep 2 ** timeout + timeout += 1 +end \ No newline at end of file diff --git a/ruby/streams/sampled_stream.rb b/ruby/streams/sampled_stream.rb new file mode 100644 index 0000000..6a8c29d --- /dev/null +++ b/ruby/streams/sampled_stream.rb @@ -0,0 +1,51 @@ +# This script connects to the Sample stream endpoint and outputs data + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +stream_url = "https://api.x.com/2/tweets/sample/stream" + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/tweets/volume-streams/api-reference/get-tweets-sample-stream +params = { + # "expansions": "author_id,referenced_tweets.id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "name" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +def stream_connect(url, bearer_token, params) + options = { + timeout: 20, + method: 'get', + headers: { + "User-Agent": "v2SampledStreamRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + request.on_body do |chunk| + puts chunk + end + request.run +end + +# Listen to the stream. +# This reconnection logic will attempt to reconnect when a disconnection is detected. +# To avoid rate limites, this logic implements exponential backoff, so the wait time +# will increase if the client cannot reconnect to the stream. +timeout = 0 +while true + stream_connect(stream_url, bearer_token, params) + sleep 2 ** timeout + timeout += 1 +end diff --git a/ruby/timelines/reverse-chron-home-timeline.rb b/ruby/timelines/reverse-chron-home-timeline.rb new file mode 100644 index 0000000..4b7ba40 --- /dev/null +++ b/ruby/timelines/reverse-chron-home-timeline.rb @@ -0,0 +1,110 @@ +require 'json' +require 'typhoeus' +require 'twitter_oauth2' + +# First, you will need to enable OAuth 2.0 in your App’s auth settings in the Developer Portal to get your client ID. +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_ID='your-client-id' +client_id = ENV["CLIENT_ID"] + +# If you have selected a type of App that is a confidential client you will need to set a client secret. +# Confidential Clients securely authenticate with the authorization server. + +# Inside your terminal you will need to set an enviornment variable +# export CLIENT_SECRET='your-client-secret' + +# Remove the comment on the following line if you are using a confidential client +# client_secret = ENV["CLIENT_SECRET"] + + +# Replace the following URL with your callback URL, which can be obtained from your App's auth settings. +redirect_uri = "https://www.example.com" + +# Start an OAuth 2.0 session with a public client +client = TwitterOAuth2::Client.new( + identifier: "#{client_id}", + redirect_uri: "#{redirect_uri}" +) + +# Start an OAuth 2.0 session with a confidential client + +# Remove the comment on the following lines if you are using a confidential client +# client = TwitterOAuth2::Client.new( +# identifier: "#{client_id}", +# secret: "#{client_secret}", +# redirect_uri: "#{redirect_uri}" +# ) + +# Create your authorize url +authorization_url = client.authorization_uri( + # Update scopes if needed + scope: [ + :'users.read', + :'tweet.read', + :'offline.access' + ] +) + +# Set code verifier and state +code_verifier = client.code_verifier +state = client.state + +# Visit the URL to authorize your App to make requests on behalf of a user +print 'Visit the following URL to authorize your App on behalf of your Twitter handle in a browser' +puts authorization_url +`open "#{authorization_url}"` + +print 'Paste in the full URL after you authorized your App: ' and STDOUT.flush + +# Fetch your access token +full_text = gets.chop +new_code = full_text.split("code=") +code = new_code[1] +client.authorization_code = code + +# Your access token +token_response = client.access_token! code_verifier + +# Make a request to the users/me endpoint to get your user ID +def users_me(url, token_response) + options = { + method: 'get', + headers: { + "User-Agent": "ReverseChronHomeTimelineSampleCode", + "Authorization": "Bearer #{token_response}" + }, + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +url = "https://api.x.com/2/users/me" +me_response = users_me(url, token_response) + +json_s = JSON.parse(me_response.body) +user_id = json_s["data"]["id"] + +# Make a request to the reverse chronological home timeline endpoint +url = "https://api.x.com/2/users/#{user_id}/timelines/reverse_chronological" + + +def reverse_chron_timeline(url, token_response) + options = { + method: 'get', + headers: { + "User-Agent": "ReverseChronTimelinesSampleCode", + "Authorization": "Bearer #{token_response}" + } + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = reverse_chron_timeline(url, token_response) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/timelines/user-mentions.rb b/ruby/timelines/user-mentions.rb new file mode 100644 index 0000000..cce22f3 --- /dev/null +++ b/ruby/timelines/user-mentions.rb @@ -0,0 +1,49 @@ +# This script uses your bearer token to authenticate and make a request to the User mentions timeline endpoint. +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the User mentions timelines. +endpoint_url = "https://api.x.com/2/users/:id/mentions" + +# Specify the User ID for this request. +id = 2244994945 #@TwitterDev's numeric User ID. + +# Add or remove parameters below to adjust the query and response fields within the payload +# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ +query_params = { + "max_results" => 100, + # "start_time" => "2020-07-01T00:00:00Z", + # "end_time" => "2020-07-02T18:00:00Z", + "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", + "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields" => "description" + # "media.fields" => "url", + # "place.fields" => "country_code", + # "poll.fields" => "options" +} + +def get_user_mentions(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent" => "v2RubyExampleCode", + "Authorization" => "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +endpoint_url = endpoint_url.gsub(':id',id.to_s()) + +response = get_user_mentions(endpoint_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/timelines/user-tweets.rb b/ruby/timelines/user-tweets.rb new file mode 100644 index 0000000..68ac34c --- /dev/null +++ b/ruby/timelines/user-tweets.rb @@ -0,0 +1,55 @@ +# This script uses your bearer token to authenticate and make a request to the User Tweets timeline endpoint. + +#Based on recent search example and updated for User mention timeline. +#Next steps: +# [] Refactor for User Tweets timeline.. +# [] Refactor for Full-archive search. + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the Recent Search API +endpoint_url = "https://api.x.com/2/users/:id/tweets" + +# Specify the User ID for this request. +id = 2244994945 #@TwitterDev's numeric User ID. + +# Add or remove parameters below to adjust the query and response fields within the payload +# TODO: See docs for list of param options: https://developer.twitter.com/en/docs/twitter-api/tweets/ +query_params = { + "max_results" => 100, + # "start_time" => "2020-07-01T00:00:00Z", + # "end_time" => "2020-07-02T18:00:00Z", + "expansions" => "attachments.poll_ids,attachments.media_keys,author_id", + "tweet.fields" => "attachments,author_id,conversation_id,created_at,entities,id,lang", + "user.fields" => "description" + # "media.fields" => "url", + # "place.fields" => "country_code", + # "poll.fields" => "options" +} + +def get_user_tweets(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent" => "v2RubyExampleCode", + "Authorization" => "Bearer #{bearer_token}" + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +endpoint_url = endpoint_url.gsub(':id',id.to_s()) + +response = get_user_tweets(endpoint_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/block_a_user.rb b/ruby/users/block_a_user.rb new file mode 100644 index 0000000..07e0b2b --- /dev/null +++ b/ruby/users/block_a_user.rb @@ -0,0 +1,86 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" +blocking_url = "https://api.x.com/2/users/#{id}/blocking" + +# Be sure to add replace id-to-block with the id of the user you wish to block. +# You can find a user ID by using the user lookup endpoint +@target_user_id = { "target_user_id": "id-to-block" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_block(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2BlockUserRuby", + "content-type": "application/json" + }, + body: JSON.dump(@target_user_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = user_block(blocking_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/followers-lookup.rb b/ruby/users/followers-lookup.rb new file mode 100644 index 0000000..6464a7e --- /dev/null +++ b/ruby/users/followers-lookup.rb @@ -0,0 +1,40 @@ +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on macOS or Linux, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the user followers +endpoint_url = "https://api.x.com/2/users/:id/followers" + +# Specify the User ID for this request. +id = 2244994945 + +# Add or remove parameters below to adjust the query and response fields within the payload +query_params = { + "max_results" => 1000, + "user.fields" => "created_at" +} + +def get_followers(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent" => "v2RubyExampleCode", + "Authorization" => "Bearer #{bearer_token}", + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +endpoint_url = endpoint_url.gsub(':id',id.to_s()) + +response = get_followers(endpoint_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/following-lookup.rb b/ruby/users/following-lookup.rb new file mode 100644 index 0000000..a912298 --- /dev/null +++ b/ruby/users/following-lookup.rb @@ -0,0 +1,40 @@ +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on macOS or Linux, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +# Endpoint URL for the user following API +endpoint_url = "https://api.x.com/2/users/:id/following" + +# Specify the User ID for this request. +id = 2244994945 + +# Add or remove parameters below to adjust the query and response fields within the payload +query_params = { + "max_results" => 1000, + "user.fields" => "created_at" +} + +def get_following(url, bearer_token, query_params) + options = { + method: 'get', + headers: { + "User-Agent" => "v2RubyExampleCode", + "Authorization" => "Bearer #{bearer_token}", + }, + params: query_params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +endpoint_url = endpoint_url.gsub(':id',id.to_s()) + +response = get_following(endpoint_url, bearer_token, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/get_users_me_with_user_context.rb b/ruby/users/get_users_me_with_user_context.rb new file mode 100644 index 0000000..24a9e14 --- /dev/null +++ b/ruby/users/get_users_me_with_user_context.rb @@ -0,0 +1,80 @@ +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +user_lookup_url = "https://api.x.com/2/users/me" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users +query_params = { + # "expansions": "pinned_tweet_id", + # "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + "user.fields": "created_at,description" +} + +def user_lookup(url, oauth_params, query_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2UserLookupRuby" + }, + params: query_params + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = user_lookup(user_lookup_url, oauth_params, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/get_users_with_bearer_token.rb b/ruby/users/get_users_with_bearer_token.rb new file mode 100644 index 0000000..eb3cedf --- /dev/null +++ b/ruby/users/get_users_with_bearer_token.rb @@ -0,0 +1,44 @@ +# This script uses your bearer token to authenticate and retrieve the specified User objects (by ID) + +require 'json' +require 'typhoeus' + +# The code below sets the bearer token from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export BEARER_TOKEN='YOUR-TOKEN' +bearer_token = ENV["BEARER_TOKEN"] + +user_lookup_url = "https://api.x.com/2/users" + +# Specify the User IDs that you want to lookup below (to 100 per request) +user_ids = "2244994945,783214" + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs +params = { + "ids": user_ids, + "expansions": "pinned_tweet_id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "name" + # "media.fields": "url", + # "place.fields": "country_code", + # "poll.fields": "options" +} + +def user_lookup(url, bearer_token, params) + options = { + method: 'get', + headers: { + "User-Agent": "v2UserLookupRuby", + "Authorization": "Bearer #{bearer_token}" + }, + params: params + } + + request = Typhoeus::Request.new(url, options) + response = request.run + + return response +end + +response = user_lookup(user_lookup_url, bearer_token, params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/get_users_with_user_context.rb b/ruby/users/get_users_with_user_context.rb new file mode 100644 index 0000000..3cc2c32 --- /dev/null +++ b/ruby/users/get_users_with_user_context.rb @@ -0,0 +1,88 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) + +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Returns a user object for one or more users specified by the requested usernames +user_lookup_url = "https://api.x.com/2/users/by" + +# Specify the usernames that you want to lookup below (to 100 per request) +usernames = "Twitter,TwitterDev" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + +# Add or remove optional parameters values from the params object below. Full list of parameters and their values can be found in the docs: +# https://developer.twitter.com/en/docs/twitter-api/users/lookup/api-reference/get-users +query_params = { + "usernames": usernames, + # "expansions": "pinned_tweet_id", + "tweet.fields": "attachments,author_id,conversation_id,created_at,entities,geo,id,in_reply_to_user_id,lang", + # "user.fields": "name" +} + +def user_lookup(url, oauth_params, query_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2UserLookupRuby" + }, + params: query_params + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = user_lookup(user_lookup_url, oauth_params, query_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/lookup_blocks.rb b/ruby/users/lookup_blocks.rb new file mode 100644 index 0000000..e174634 --- /dev/null +++ b/ruby/users/lookup_blocks.rb @@ -0,0 +1,81 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +blocking_url = "https://api.x.com/2/users/#{id}/blocking" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_block(url, oauth_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2BlocksLookupRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = user_block(blocking_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/lookup_mutes.rb b/ruby/users/lookup_mutes.rb new file mode 100644 index 0000000..7c766ae --- /dev/null +++ b/ruby/users/lookup_mutes.rb @@ -0,0 +1,81 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a Mutes lookup request (by usernames) with OAuth 1.0a authentication (user context) +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" + +muting_url = "https://api.x.com/2/users/#{id}/muting" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def users_muted(url, oauth_params) + options = { + :method => :get, + headers: { + "User-Agent": "v2MutesLookupRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = users_muted(muting_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) \ No newline at end of file diff --git a/ruby/users/mute_a_user.rb b/ruby/users/mute_a_user.rb new file mode 100644 index 0000000..2670452 --- /dev/null +++ b/ruby/users/mute_a_user.rb @@ -0,0 +1,85 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +id = "your-user-id" +muting_url = "https://api.x.com/2/users/#{id}/muting" + +# Be sure to add replace id-to-mute with the id of the user you wish to mute. +# You can find a user ID by using the user lookup endpoint +@target_user_id = { "target_user_id": "id-to-mute" } + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_mute(url, oauth_params) + options = { + :method => :post, + headers: { + "User-Agent": "v2muteUserRuby", + "content-type": "application/json" + }, + body: JSON.dump(@target_user_id) + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + + + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + + +response = user_mute(muting_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) diff --git a/ruby/users/unblock_a_user.rb b/ruby/users/unblock_a_user.rb new file mode 100644 index 0000000..3491dc3 --- /dev/null +++ b/ruby/users/unblock_a_user.rb @@ -0,0 +1,86 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +# It then makes a User lookup request (by usernames) with OAuth 1.0a authentication (user context) + +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +source_user_id = "your-user-id" + +# Be sure to add replace id-to-unblock with the user id of the user you wish to unblock. +# You can find a user ID by using the user lookup endpoint +target_user_id = "id-to-unblock" + +# Returns a user object for one or more users specified by the requested usernames +user_unblock_url = "https://api.x.com/2/users/#{source_user_id}/blocking/#{target_user_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_unblock(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2UnblockUserRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = user_unblock(user_unblock_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body)) + +# Note: If you were following the user you blocked, you have removed your follow and will have to refollow the user, even if you did unblock the user. diff --git a/ruby/users/unmute_a_user.rb b/ruby/users/unmute_a_user.rb new file mode 100644 index 0000000..6c02da4 --- /dev/null +++ b/ruby/users/unmute_a_user.rb @@ -0,0 +1,82 @@ +# This script implements the PIN-based OAuth flow to obtain access tokens for a user context request +require 'oauth' +require 'json' +require 'typhoeus' +require 'oauth/request_proxy/typhoeus_request' + +# The code below sets the consumer key and secret from your environment variables +# To set environment variables on Mac OS X, run the export command below from the terminal: +# export CONSUMER_KEY='YOUR-KEY', CONSUMER_SECRET='YOUR-SECRET' +consumer_key = ENV["CONSUMER_KEY"] +consumer_secret = ENV["CONSUMER_SECRET"] + +# Be sure to replace your-user-id with your own user ID or one of an authenticating user +# You can find a user ID by using the user lookup endpoint +source_user_id = "your-user-id" + +# Be sure to add replace id-to-unmute with the user id of the user you wish to unmute. +# You can find a user ID by using the user lookup endpoint +target_user_id = "id-to-unmute" + +# Returns a user object for one or more users specified by the requested usernames +user_unmute_url = "https://api.x.com/2/users/#{source_user_id}/muting/#{target_user_id}" + +consumer = OAuth::Consumer.new(consumer_key, consumer_secret, + :site => 'https://api.x.com', + :authorize_path => '/oauth/authenticate', + :debug_output => false) + +def get_request_token(consumer) + + request_token = consumer.get_request_token() + + return request_token +end + +def get_user_authorization(request_token) + puts "Follow this URL to have a user authorize your app: #{request_token.authorize_url()}" + puts "Enter PIN: " + pin = gets.strip + + return pin +end + +def obtain_access_token(consumer, request_token, pin) + token = request_token.token + token_secret = request_token.secret + hash = { :oauth_token => token, :oauth_token_secret => token_secret } + request_token = OAuth::RequestToken.from_hash(consumer, hash) + + # Get access token + access_token = request_token.get_access_token({:oauth_verifier => pin}) + + return access_token +end + + +def user_unmute(url, oauth_params) + options = { + :method => :delete, + headers: { + "User-Agent": "v2UnmuteUserRuby" + } + } + request = Typhoeus::Request.new(url, options) + oauth_helper = OAuth::Client::Helper.new(request, oauth_params.merge(:request_uri => url)) + request.options[:headers].merge!({"Authorization" => oauth_helper.header}) # Signs the request + response = request.run + + return response +end + +# PIN-based OAuth flow - Step 1 +request_token = get_request_token(consumer) +# PIN-based OAuth flow - Step 2 +pin = get_user_authorization(request_token) +# PIN-based OAuth flow - Step 3 +access_token = obtain_access_token(consumer, request_token, pin) + +oauth_params = {:consumer => consumer, :token => access_token} + +response = user_unmute(user_unmute_url, oauth_params) +puts response.code, JSON.pretty_generate(JSON.parse(response.body))