hunterlarco / twitter-v2 Goto Github PK
View Code? Open in Web Editor NEWAn asynchronous client library for the Twitter REST and Streaming API's
License: MIT License
An asynchronous client library for the Twitter REST and Streaming API's
License: MIT License
Twitter streaming consistently disconnects at the 21 to 22 second mark depending on lag. It seems they have adjusted their heartbeat length to be slower. Please adjust the hardcoded amount to 30 seconds. There is a referenced open PR that allows for it to be adjustable.
See: #63
Expected behavior:
The stream to stay open. It is closing before it receives the heartbeat.
Actual behavior:
The stream closes too early.
Reproduces how often:
It depends on the time of day. It seems Twitter has extended their heartbeat length to exactly 20 seconds. Any lag causes a disconnect.
v1.0.7
Some chunks coming from the stream API look like the example below.
First, would it make sense to report whatever is coming in .errors[]
as TwitterError
?
Second, would the code become more elegant by disconnecting explicitly on receiving OperationalDisconnect
?
const chunk = {
errors: [
{
title: 'operational-disconnect',
disconnect_type: 'OperationalDisconnect',
detail: 'This stream has been disconnected for operational reasons.',
type: 'https://api.twitter.com/2/problems/operational-disconnect',
},
],
}
My code was naively expecting to receive consistently formed chunks and errored out on this unexpected shape. Which is kind of fine, but since this is an explicit error, it probably would make sense to centralize its handling in the twitter-v2.
Leaving this for all library users to handle by themselves is also an option, a wasteful one though.
Hi (again), this is more of a feature request: I like the provision of stream data through an async iterator. It's clean and simple. But I am trying to implement a reconnection logic and there seems no way to know the status of the connection 'from the outside' as twitters 'ping' signals are not propagated by the iterator (or I am missing something).
ImO it would be helpful to either
Cheers,
Thilo
PS I am aware that this is a rather small project and my limited JS skills mean that I am unlikely of much help with the code. Just indicate if you think this won't be taken much further and I'll stop bugging you with issues.
Hello,
As i said in the title i can't reply to a specific tweet using his id, i probably do it wrong but it look like good for me,
so could someone help me ? Thank you for how will help me.
My tokens are good because i can get throw the stream all tweet ( with client2) , but it's not working for client
let tweetsRawData = await client.get( 'users/1407591434660761602/tweets', { tweet: { fields: ['attachments,created_at,lang,text'], }, media: { fields: ['preview_image_url,type,url'] } }, );
Does not the create the to be expected call to:
https://api.twitter.com/2/users/1407591434660761602/tweets?tweet.fields=lang&**expansions**=attachments.media_keys&media.fields=preview_image_url,url
Result is this:
https://api.twitter.com/2/users/1407591434660761602/tweets?tweet.fields=attachments%2Ccreated_at%2Clang%2Ctext&media.fields=preview_image_url%2Ctype%2Curl
Also a "hint" in the documentation, that Twitter sends the "inclues" in a 2nd JSON Part would be nice.
some endpoints need OAuth2 Application-only auth, but afaik this library only supports 1.0a.
I'm trying to search the recent tweets for a specific user. Here's the URL if I use Insomnia:
https://api.twitter.com/2/tweets/search/recent?start_time=2021-04-23T00:00:00Z&query=from%3A_TWITTER_HANDLE_GOES_HERE&tweet.fields=id,author_id,text
and GET on that URL returns data. This does not work:
twitterClient.get('tweets/search/recent', {
query: 'from%3Athe_churchnews',
start_time: '2021-04-23T00:00:00Z',
});
In addition, the commented out parts of the above object cause an error, which is why they are commented out. I've looked at the source code to try and build that object correctly, but haven't been able to get it to work properly.
In addition, in the URL string I have the tweet.fields
query param. I tried adding it to the options object in both of the following ways, with no success. The first way causes an error, the second way there is no error but I'm not sure if it's working since I don't get any data back.
tweet: {
fields: 'id,author_id,text',
},
// And
'tweet.fields': 'id,author_id,text',
Any docs or pointers here would be greatly appreciated.
async function getTweets() {
const dt = new Date();
dt.setHours(dt.getHours() - 12);
const dateString = dt.toISOString();
const { data } = await twitterClient.get('tweets/search/recent', {
query: 'from%3A_twitter_handle',
start_time: dateString,
'tweet.fields': 'id,author_id,text',
});
console.log(data);
return data;
}
Expected behavior:
Tweets should print to the console
Actual behavior:
undefined
is printed to the console.
Reproduces how often:
Every time
v1.1.0
Here is my code
let twitter = require("twitter-v2");
let client = new twitter({
consumer_key: "...",
consumer_secret: "...",
access_token_key: "...",
access_token_secret: "..."
})
const { data } = client.get('search/tweets', { q: 'Kawaki', count: 5 });
console.log(data);
and when i run it, i get following error
C:\Users\<USER>\node_modules\twitter-v2\src\Credent
ials.js:129
this._bearer_token = bearer_token.startsWith('Bearer ')
^
TypeError: Cannot read property 'startsWith' of undefined
at new Credentials (C:\Users\<USER>\node_module
s\←[4mtwitter-v2←[24m\src\Credentials.js:129:39)
at new Twitter (C:\Users\<USER>\node_modules\←[
4mtwitter-v2←[24m\src\twitter.js:30:14)
at Object.<anonymous> (C:\Users\<USER>\index.js
:3:14)
←[90m at Module._compile (internal/modules/cjs/loader.js:1118:30)←[39m
←[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1138:1
0)←[39m
←[90m at Module.load (internal/modules/cjs/loader.js:982:32)←[39m
←[90m at Function.Module._load (internal/modules/cjs/loader.js:875:14)←[39m
←[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_ma
in.js:71:12)←[39m
←[90m at internal/main/run_main_module.js:17:47←[39m
what should i do ?
It would be helpful to be able to iterate through paginated data, via an async iterator.
At the moment the user has to manually handle paginated responses by reading meta.next_token
and setting it as params.pagination_token
on a new request.
It would be helpful if it was possible to use for await (const item of client.get(path, params)) { … }
(where item
is an item from the data
array in each response) to iterate through each item automatically.
Making requests in a do { … } while (params.pagination_token)
loop.
The streams part of twitter-v2 is unreliable. I've set it to monitor five twitter accounts that tweet about once every six hours.
Expected behaviour:
Should be able to run indefinitely. twitter-v2 should not disconnect the stream just because it thinks the stream is unresponsive. The sample code by Twitter themselves does not have this behaviour.
Actual behaviour:
Streams randomly hit this._closeWithError
.
at Timeout.<anonymous> (/home/rctgamer3/project/node_modules/twitter-v2/src/TwitterStream.js:50:30)
at listOnTimeout (internal/timers.js:554:17)
at processTimers (internal/timers.js:497:7)
Stream timeout's, and throws a TwitterError that the stream is unresponsive.
Reproduces how often:
Always, the only variable is the time until it closes the stream.
1.0.8
If you need any further information to triage things, let me know.
Hey! I was thinking it would be great if someone more experienced than myself could code a nice general retry logic in case a steam disconnects and throws a TwitterError
error. Would be cool to have it in README instead of "probably should have retry logic here" :)
Well, my stream died a few times without me noticing ;) Also would useful when you restart an app and stream is already in use.
I've tried to implement something on my own but I've noticed sometimes the stream doesn't reconnect, so there must be something wrong with my approach. Would rather not post it. ;)
Currently, while Credentials
, CredentialsArgs
, TwitterStream
, etc. are defined in TypeScript definition files, and included in the build, they cannot be imported without digging into the structure of the package:
import Credentials, { CredentialsArgs } from "twitter-v2/build/Credentials";
import TwitterStream from "twitter-v2/build/TwitterStream";
With an index.ts
file that exports these types/class definitions, it could simplify the importing structure alongside the main client:
import Twitter, { Credentials, CredentialsArgs, TwitterStream } from "twitter-v2";
For one, users can more easily figure out what is exported for public use through the index.ts
file - there may be certain types/classes that aren't meant to be publicly exported that won't exist in here, but can be used internally. It also just cleans up the number of imports that a user might have for various parts of the package, without needing to know what the structure of the package looks like.
On a related note, it may be worth defining the files
property in the package.json
file which would send out the built files only - there's no need to pack up the src/*.ts
files when consumers are actually using the build/*.js
and build/*.d.ts
files.
I hope this library can support these apis
https://developer.twitter.com/en/docs/twitter-api/users/follows/api-reference/delete-users-source_id-following
Im trying to create first step, from oficial instruction
const Twitter = require('twitter-v2');
const client = new Twitter({
bearer_token: token,
consumer_key: '***',
consumer_secret: '***',
});
const { data } = await client.get('tweets', { ids: '1228393702244134912' });
console.log(data);
And get an error:
TypeError: url_1.URL is not a constructor.
I cant undestand what im do wrong, how i can get tweets from specific user? Help pls/
Hello,
where might I find a list of the urlParams mentioned in the docs?
e.g.:
client.get(path, urlParams);
Thank you
I just want to get a tweet as a json from it's id.
I tried the following, but it won't work, I get this error.
const express = require("express");
const app = express();
const Twitter = require("twitter-v2");
const axios = require("axios");
var client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
bearer_token: process.env.TWITTER_BEARER_TOKEN
});
app.get("/", async (request, response) => {
const { data } = await client.get("tweets", { ids: "1343068487405596672" });
response.send(data);
});
const listener = app.listen(process.env.PORT, () => {
console.log("Your app is listening on port " + listener.address().port);
});
(node:3865) UnhandledPromiseRejectionWarning: Error: Client Forbidden: When authenticating requests to the Twitter API v2 endpoints, you must use keys and tokens from a Twitter developer app that is attached to a Project. You can create a project via the developer portal.
at Function.module.exports.fromJson (/rbd/pnpm-volume/9f6f5ef1-e8fd-449a-bc06-21e1a90a3bac/node_modules/.registry.npmjs.org/twitter-v2/1.0.0/node_modules/twitter-v2/src/TwitterError.js:29:12)
at Twitter.get (/rbd/pnpm-volume/9f6f5ef1-e8fd-449a-bc06-21e1a90a3bac/node_modules/.registry.npmjs.org/twitter-v2/1.0.0/node_modules/twitter-v2/src/twitter.js:46:32)
at processTicksAndRejections (internal/process/task_queues.js:88:5)
at async /app/server.js:13:20
(node:3865) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 5)
Hi,
this is very very likely NOT an issue with twitter-v2, but I am hoping someone here may have a thought: My filtered stream disconnects every 5 minutes without raising an error. Reconnect works just fine, but I fear I am losing data in the meantime. I am able to reproduce this across two different machines with different internet connections and different twitter accounts.
I have used twitter-v2 for several weeks without seeing this happening, it started a couple of days ago. I made a few changes to my code and updated to a more recent version of twitter-v2, but none of this seems a plausible explanation for the disconnects.
Thanks for any thoughts or suggestions!
Thilo
Are there any plans for writing TypeScript definitions for this package? I was planning on writing a wrapper library in TS to provide some utility functions around these base API calls and I've found myself filling in some of the types for this package anyway.
https://twittercommunity.com/t/post-request-returning-error-401-unauthorized/162950/4
following the example in the README, let response = await client.get('tweets', { ids: id })
works as expected, but let response = await client.post('tweets', { text: message })
fails with { code: 401, details: 'Unauthorized' }
. nodejs 17.2.0, windows.
It's expected that POST should authenticate using the same method and send a tweet successfully.
Full code example:
const Twitter = require("twitter-v2")
const client = new Twitter({
consumer_key: process.env.TWITTER_CONSUMER_KEY,
consumer_secret: process.env.TWITTER_CONSUMER_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN_KEY,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET
});
async function sendTweet(message) {
try {
const response = await client.post('tweets', { text: message })
console.log(response)
} catch (err) {
console.error(err)
}
}
async function getTweet(id) {
try {
const response = await client.get('tweets', { ids: id })
console.log(response)
} catch (err) {
console.error(err)
}
}
sendTweet('test tweet!')
getTweet('1228393702244134912')
In Twitter V2, the errors field of what's returned by Twitter is a legitimate field.
e.g. When we are looking up a tweet id that has been suspended, we would look in the errors field for this case.
Thus, it should not result in an error thrown, instead just return the errors field results
e.g. This tweet is from an account that is suspended, so
client.get('tweets', {ids:'1000082502030065665'})
is a valid api call
It should return:
{"errors":[{"value":"1000082502030065665","parameter":"ids","resource_type":"tweet","section":"data","title":"Authorization Error","detail":"Sorry, you are not authorized to see the Tweet with ids: [1000082502030065665].","type":"https://api.twitter.com/2/problems/not-authorized-for-resource"}]}
Dear sir,
I was given oauth v2 credentials, is there an option in your library for the bearer token style auth yet?
Thanks
When I used Node 12 (LTS)
I receive this warning, not sure if it is complicated to update.
warning twitter-v2 > [email protected]: This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in.
Trying to run the readme example, it is throwing error Unhandled Promise Rejection: TypeError: undefined is not a constructor (evaluating 'new url_1.URL(
https://api.twitter.com/2/${endpoint}`)')`.
const Twitter = require('twitter-v2');
const client = new Twitter({
consumer_key: '',
consumer_secret: '',
access_token_key: '',
access_token_secret: '',
});
const { data } = await client.get('tweets', { ids: '1228393702244134912' });
console.log(data);
Expected behavior:
It should console the response
Actual behavior:
It throws error as shown in the above screenshot
Reproduces how often:
All the time
1.1.0
Sorry, a bit lost in the documentation, how to get all tweets of a user by screen_name or ID?
let { data } = await twitterclient.get('tweets', { screen_name: 'twitterapiscreenname' });
Thanks
Hi again,
If I log a new Twitter object, I notice it says it's using Oauth 1.0
Isn't the app auth w/ bearer token oauth v2.0? Reference: https://developer.twitter.com/en/docs/authentication/oauth-2-0
This:
import * as Twitter from 'twitter-v2';
import { apiKey, apiSecretKey, bearerToken } from 'keys';
const client = new Twitter({
consumer_key: apiKey,
consumer_secret: apiSecretKey,
bearer_token: bearerToken,
});
console.log(client);
Returns this:
Twitter {
credentials: Credentials {
_consumer_key: '...',
_consumer_secret: '...',
_bearer_token: '...',
_access_token: undefined,
_access_token_secret: undefined,
_bearer_token_promise: null,
_oauth: OAuth {
consumer: [Object],
nonce_length: 32,
version: '1.0',
parameter_seperator: ', ',
realm: undefined,
last_ampersand: true,
signature_method: 'HMAC-SHA1',
hash_function: [Function: hash_function],
body_hash_function: [Function: hash_function]
}
}
}
FWIW, I'm GETting tweets just fine. Is the stated oauth version anything I should be concerned about?
Thanks
undefined
(node:7472) UnhandledPromiseRejectionWarning: Error: Unauthorized
at Function.module.exports.fromJson (C:\Users\Asus\Desktop\Veljko\twitterAPI
\node_modules\twitter-v2\src\TwitterError.js:25:12)
at Twitter.get (C:\Users\GV9Jm2u7rmsCe65wKzPTw5jtS38n2tVEGie_modules\twitter
-v2\src\twitter.js:46:32)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:7472) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This
error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). To termina
te the node process on unhandled promise rejection, use the CLI flag `--unhandle
d-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejectio
ns_mode). (rejection id: 1)
(node:7472) [DEP0018] DeprecationWarning: Unhandled promise rejections are depre
cated. In the future, promise rejections that are not handled will terminate the
Node.js process with a non-zero exit code.
I'm a Samsung developer, and work on Bixby Project. I found a bug while developing a new feature of Twitter.
This feature works getting the user to explore tabs (For You, News, Sports, Entertainment).
Expected behavior:
Opens the Entretainment Tab
Actual behavior:
It keeps in the same initial tab of Sports, instead of going to Entratainment
Reproduces how often:
Always 100%
Twitter API v2
This issue only happens when using the Twitter app, when using twitter on browser it works normally.
If possible please contact us: [email protected]
await is only valid in async function
when running getting started example in readme
create a node app with the following code (copied from readme):
const Twitter = require('twitter-v2');
const client = new Twitter({
bearer_token: //bearer_token
});
const { data } = await client.get('tweets', { ids: '1228393702244134912' });
console.log(data);
Expected behavior:
should log the output of the tweet
Actual behavior:
console error:
await is only valid in async function
Reproduces how often:
100%
^1.1.0
node_modules/twitter-v2/src/Credentials.d.ts:29:37 - error TS2304: Cannot find name 'ApplicationCredentials'.
export class Credentials implements ApplicationCredentials, UserCredentials {
Hey! First of all - great initiative and awesome work on pushing the first twitter v2 client for node.js, thanks for that 👍 I am having some troubles using the user auth and wanted to seek your help. First question - is it supported by the library already? Second question - do the credentials that are working with API v1 work with version two also? Now closer to the code :
access_token
without key
const client = new Twitter({
consumer_key: '',
consumer_secret: '',
access_token_key: '',
access_token_secret: '',
});
async function main() {
const test = new TwitterV2({
consumer_key: TWITTER_KEY,
consumer_secret: TWITTER_SECRET,
access_token: TWITTER_TOKEN_KEY,
access_token_secret: TWITTER_TOKEN_SECRET,
});
const { data } = await test.get('tweets', { ids: '1304072330839306240' });
console.log(data);
}
main();
The error is following:
Unauthorized
at Function.module.exports.fromJson (path_to_project/node_modules/twitter-v2/src/TwitterError.js:25:12)
Which brings me to the question - do I need to do some specific steps for this to work outside the lib itself like on twitter dev acc or? I want to use it to get impression counts for some tweets.
Any help appreciated + if you need any help yourself with the library, I am all up to give you a hand here or there
You need to sign up for the NEW dev dashboard, add your app to the project supported to version two and finally you may want to regenerate you access token and access token secret. After these steps it shall work correctly with supplied credentials. Maybe this deserves a place in docs for now, as Twitter migrates it's api 😀
Twitter gives you 5 values:
This code completely ignores #3 above ( bearer token ) and when you run without that values in the sample it just returns "unauthorized".
Hi, is it possible to post twit with version 2? Could I get sample codes for this: client.post(path, body, urlParams);
?
I'm getting an error when trying to post. Maybe the endpoint is not yet available on version 2?
Hello, I'm using this library to create a back-end to an App I'm building for my portfolio, so I don't plan on releasing it on an App Store.
One thing that it does is that it listens to tweets of the accounts the user has added to the app.
Since I'm still building it, I oftenly have to change one or two lines of code in the back-end, then save and it starts running again. But I'm having this annoying problem, that whenever the app stops and starts running again after a short time, the stream doesn't start so it can't listen to tweets.
TwitterError: ConnectionException: This stream is currently at the maximum allowed connection limit.
at Function.module.exports.fromJson (/home/samuel/stlk-api/node_modules/twitter-v2/src/TwitterError.js:29:12)
at Stream.<anonymous> (/home/samuel/stlk-api/node_modules/twitter-v2/src/TwitterStream.js:60:40)
at Stream.emit (node:events:379:20)
at Stream.EventEmitter.emit (node:domain:470:12)
at drain (/home/samuel/stlk-api/node_modules/through/index.js:36:16)
at Stream.stream.queue.stream.push (/home/samuel/stlk-api/node_modules/through/index.js:45:5)
at emit (/home/samuel/stlk-api/node_modules/split/index.js:37:14)
at Stream.<anonymous> (/home/samuel/stlk-api/node_modules/split/index.js:60:7)
at _end (/home/samuel/stlk-api/node_modules/through/index.js:65:9)
at Stream.stream.end (/home/samuel/stlk-api/node_modules/through/index.js:74:5) {
details: 'https://api.twitter.com/2/problems/streaming-connection'
}
I've tried to listen to the stop events, but to no success
process.on('SIGTERM', () => {
console.info('SIGTERM signal received.');
console.log('Closing http server.');
twitterService.closeStream();
});
process.on ('SIGINT', () => {
console.info('SIGINT signal received.');
console.log('Closing http server.');
twitterService.closeStream();
process.exit(0);
});
Is there anything I can do to fix or workaround this?
When adding multiple query operators in urlParams in the form of an object, it throws an error. On checking it closely, it looks like the error is due to url module in applyParameters function in the source code that encodes space between the parameters as +
and Twitter API expects it to be encoded as %20
. The code mentioned in the examples results in the same error.
node v12, v14, v16
const urlParams = {
'query' : 'conversation_id:1305403243388829696 from:pbshgthm',
...other_params
}
client.get(`tweets/search/recent`,urlParams);
Expected behavior:
conversation_id:1305403243388829696 from:pbshgthm
gets encoded as conversation_id%3A1305403243388829696%20from%3Apbshgthm
API call goes through
Actual behavior:
conversation_id:1305403243388829696 from:pbshgthm
gets encoded as conversation_id%3A1305403243388829696+from%3Apbshgthm
Results in the following error
handledPromiseRejectionWarning: Error: Unauthorized at Function.module.exports.fromJson (/home/runner/threads/node_modules/twitter-v2/build/TwitterError.js:23:16)
Reproduces how often:
Always
1.1.0 (latest)
N.A.
When trying to apply url parameters to links that have :parameters, it will return 'One or more parameters to your request was invalid.'
The problem code
const {data} = client.get('users/by/username/:username',{username :'INSERT NAME HERE'});
It will return the error I mentioned above.
Not sure if this is already implemented, but adding support for creating filtered streams with rules will be great.
Can you add an example on how to get streams using urlParams?
I'm stuck trying to get real time tweets from specific accounts. The streaming example is too simple to assist me.
I read the official API docs and it didn't help
Hey, i just tried this out and it works a treat! Great job
I was wondering if i could help out at all?
There were one or two things i had to dig around the api docs for which might benefit from some extra code snippet examples in the README
For example i'm trying to get the last 100 tweets for my username and it took me a while to work out how to pass the params
const { data } = await client.get('tweets/search/recent', {
query: 'PaulieScanlon',
max_results: '100',
tweet: {
fields:
'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,withheld',
},
})
working of code: I am making a twitter bot that tweet from my text file named as tweet.txt after fixed time interval using javascript language.
Code:
const Twitter = require('twitter-v2');
const fs = require('fs');
const client = new Twitter({
consumer_key:'',
consumer_secret:'',
access_token_key:'',
access_token_secret:'',
});
function readTweetsFromFile() {
const tweets = fs.readFileSync('tweets.txt', 'utf8').split('\n');
return tweets.filter((tweet) => tweet.trim() !== '');
}
async function postTweet(tweet) {
console.log('Posting tweet:', tweet);
try {
console.log('client:', client);
console.log('client.tweets:', client.tweets);
console.log('client.tweets.createTweet:', client.tweets.createTweet);
const response = await client.tweet.createTweet({
text: tweet,
});
console.log('Tweet posted successfully:', response.data.text);
} catch (error) {
console.error('Error posting tweet:', error);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', error.response.data);
}
}
}
const tweets = readTweetsFromFile();
const interval = 1000 * 60 * 60; // 1 hour
function tweetInterval() {
for (let i = 0; i < tweets.length; i++) {
setTimeout(() => {
postTweet(tweets[i]);
}, interval * i);
}
}
tweetInterval();
setInterval(tweetInterval, interval * tweets.length);
const Twitter = require('twitter-v2');
const fs = require('fs');
const client = new Twitter({
consumer_key:'',
consumer_secret:'',
access_token_key:'',
access_token_secret:'',
});
function readTweetsFromFile() {
const tweets = fs.readFileSync('tweets.txt', 'utf8').split('\n');
return tweets.filter((tweet) => tweet.trim() !== '');
}
async function postTweet(tweet) {
console.log('Posting tweet:', tweet);
try {
console.log('client:', client);
console.log('client.tweets:', client.tweets);
console.log('client.tweets.createTweet:', client.tweets.createTweet);
const response = await client.tweet.createTweet({
text: tweet,
});
console.log('Tweet posted successfully:', response.data.text);
} catch (error) {
console.error('Error posting tweet:', error);
if (error.response) {
console.error('Response status:', error.response.status);
console.error('Response data:', error.response.data);
}
}
}
const tweets = readTweetsFromFile();
const interval = 1000 * 60 * 60; // 1 hour
function tweetInterval() {
for (let i = 0; i < tweets.length; i++) {
setTimeout(() => {
postTweet(tweets[i]);
}, interval * i);
}
}
tweetInterval();
setInterval(tweetInterval, interval * tweets.length);
Error message"
C:\Users\HANZLA\Desktop\twitter_bot>node index.js
Posting tweet: "Opportunities multiply as they are seized." - The Art of War by Sun Tzu
Error posting tweet: TwitterError: Unauthorized
at module.exports.fromJson (C:\Users\HANZLA\Desktop\twitter_bot\node_modules\twitter-v2\build\TwitterError.js:23:16)
at Twitter.post (C:\Users\HANZLA\Desktop\twitter_bot\node_modules\twitter-v2\build\twitter.js:63:49)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async postTweet (C:\Users\HANZLA\Desktop\twitter_bot\index.js:19:22) {
code: 401,
details: 'Unauthorized'
}
I double check all the api keys and access token keys
this is what it gave in terminal when i update the twitter v-2
library
"up to date, audited 8 packages in 4s
2 high severity vulnerabilities
Some issues need review, and may require choosing
a different dependency."
Hi there! Thanks for your new JavaScript library. Just to let you know we've added a listing on the Twitter Tools & Libraries page (with the note that it is in alpha) :-)
Feel free to add a shields.io version badge to your README, if you'd like.
Our Libraries and SDKs forum welcomes any further announcements.
It works 100% perfectly when tweets/search/recent
, but as soon as I switch to tweets/search/all
, it falls apart
Works:
const { data } = await client.get("tweets/search/recent", { query: "test" });
Does not work:
const { data } = await client.get("tweets/search/all", {
query: "test",
start_time: yesterday.toUTCString(),
end_time: new Date().toUTCString()
});
If it omit start_time
and end_time
, it gives:
Error: Unsupported Authentication: Authentication with OAuth 1.0a User Context is forbidden. Please, make the request with OAuth 2.0 Bearer Token authentication.
I am doing a simple get request like this for a tweet id I have grabbed using V1.1 API
response = await client.get('tweets', { ids: '1341761249646956500' });
if (response) {
console.log(data);
}
It is responding with this error
detail:'Could not find tweet with ids: [1341761249646956500].'
parameter:'ids'
resource_type:'tweet'
title:'Not Found Error'
type:'https://api.twitter.com/2/problems/resource-not-found'
value:'1341761249646956500'
First time trying to use the API in my TypeScript project and I see that there is an issue with the crypto dependency of the package.
new Twitter(opts)
NOTE: TypeScript compilation does not complain here.
Expected behavior:
The package to have all of it's dependencies.
Actual behavior:
Crypto is needed but it is not included as a dependency, thus WebPack is unhappy.
resolve 'crypto' in '/Users/keneucker/Dev/biketag-api/node_modules/twitter-v2/build'
Parsed request is a module
using description file: /Users/keneucker/Dev/biketag-api/node_modules/twitter-v2/package.json (relative path: ./build)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
/Users/keneucker/Dev/biketag-api/node_modules/twitter-v2/build/node_modules doesn't exist or is not a directory
looking for modules in /Users/keneucker/Dev/biketag-api/node_modules/twitter-v2/node_modules
single file module
using description file: /Users/keneucker/Dev/biketag-api/node_modules/twitter-v2/package.json (relative path: ./node_modules/crypto)
no extension
Reproduces how often:
100%
latest (1.1.0)
So I am building react application that allows users to login using twitter auth from firebase and once they login it displays their user timeline. So I am trying to use this npm package to be able to give me the user's twitter username which I will pass into another component to retrieve the user timeline to be displayed.
I made sure to install the twitter-v2 package, and I set up my client variable with all the needed keys. Right now I am trying to test it out to see if it works by retrieveing tweets with a tweets id:
But then I get this weird issue:
I also made sure this app is inside a approved project allowed to use the v2 endpoint and I have the correct keys to be able to pass in. I was wondering do you guys know how I would be able to fix this issue? Thank you all for the help I really appreciate it!
I'm trying to get the recent tweets from an user excluding the retweets.
The documentation says that I can use -is:retweet
on my query and I tried this:
const client = new Twitter({
consumer_key: process.env.TWITTER_API_KEY,
consumer_secret: process.env.TWITTER_API_SECRET,
access_token_key: process.env.TWITTER_ACCESS_TOKEN,
access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET,
});
const getLatestTweets = async (limit = 20) => {
const { data } = await client.get('tweets/search/recent', {
query: 'from:levxyca -is:retweet',
'tweet.fields': 'created_at,public_metrics,entities',
max_results: limit,
});
if (!data) { /* Not important for this issue. :D */ }
return data;
};
getLatestTweets();
The point is on query: 'from:levxyca -is:retweet'
. If a change it to query: 'from:levxyca'
, I can get the user tweets but I need to remove the retweets manually. When I add the -is:retweet
I get the error specified below.
Do I need to do any dealings with my query?
Actual behavior:
I'm getting a Unauthorized error:
:\Users\Me\Desktop\Repositories\pandadomalbot\node_modules\twitter-v2\build\TwitterError.js:23
return new module.exports(json.title, json.status, json.detail);
^
TwitterError: Unauthorized
at Function.module.exports.fromJson (C:\Users\Me\Desktop\Repositories\pandadomalbot\node_modules\twitter-v2\build\TwitterError.js:23:16)
at Twitter.get (C:\Users\Me\Desktop\Repositories\pandadomalbot\node_modules\twitter-v2\build\twitter.js:43:49)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async getLatestTweets (C:\Users\Me\Desktop\Repositories\pandadomalbot\utils\twitter.js:35:20)
at async getTodaysLiveAnnouncement (C:\Users\Me\Desktop\Repositories\pandadomalbot\utils\twitter.js:70:18)
at async Object.exports.default (C:\Users\Me\Desktop\Repositories\pandadomalbot\commands\rt.js:9:19) {
code: 401,
details: 'Unauthorized'
}
1.1.0
Thanks a lot for this package, it seems to make my twitter life substantially easier! A small issue I stumbled upon:
consumer_key and consumer_secret are required and if not present the validation function in Credentials.js throws an error. However, app auth and streaming work fine just with the bearer token – with the advantage that the token can be used elsewhere, e.g. to update rules. I commented the lines out and streaming works fine.
This is more of a question. In what scenario would the stream exit silently? Is there a way to capture it then attempt to reconnect? Thanks.
My Twitter bot exit silently from time to time without any error messages. My dev account only has this stream and the stream is only watching one account(1 or 2 tweets per day).
async function consumeStream() {
try {
const client = new Twitter(TWITTER_AUTH);
const stream = client.stream('tweets/search/stream');
for await (const { data } of stream) {
if (data) {
console.log(`Got new tweet ${data.id}`);
const link = `https://twitter.com/i/web/status/${data.id}`;
if (data.text.match(/(event|update|issue|maintenance)/i)) {
await sendMessageThenPublish(CHANNEL_ID_AUTOPUBLISH, link);
}
else {
await sendMessage(CHANNEL_ID_BACKUP, link);
}
}
}
}
catch (err) {
console.error(err);
await sendMessage(CHANNEL_ID_BACKUP, `An error occurred while watching twitter stream. Restart in 5 mins!`);
await new Promise(r => setTimeout(r, 5 * 60 * 1000)); // wait 5 mins
await consumeStream();
}
}
Attempting to get the username of a tweet author doesn't return information but also doesn't return an error
const params = {
query:'"happiness is" -sad -worst -sucks -never -bad -disappointing -is:retweet lang:en -has:mentions -has:hashtags',
expansions:'author_id',
max_results:100,
user:{
fields: ['username']
}
}
const { data: tweets } = await client.get('tweets/search/recent', params)
console.log(tweets)
Expected behavior:
return user fields in console log
Actual behavior:
{
author_id: '731951078',
id: '1398876897568776192',
text: 'Happiness is the only option no matter what What mean to be will 🙌🏻'
},
Reproduces how often:
100%
latest
N/A
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.