Hi everyone,
Feedback is welcome on this!
I found a way to Tweet using the Twitter API v2 leveraging on node-twitter-api-v2 module using a free tier app (Tweets - post up to 1500 Tweets per month)
1. App Setup on Twitter
Ensure you have set up your Twitter App correctly in the https://developer.twitter.com/en/portal/apps
You need to attach the app to a project. You need also the following credentials:
- appKey: 'API Key',
- appSecret: ' API Key Secret',
- accessToken: 'Access token',
- accessSecret: 'Access Token secret'
2. Twitter-api-v2 module import in node-red
Import the module in node-red: twitter-api-v2 in the setup tab by adding twitter-api-v2 with the + - this creates a module called twitterApiV2
3. Usage
Use the lib as twitterApiV2 in your code :
const Twitter = twitterApiV2.default;
4. Sample flow (please change the credentials, or find a better secured way to send them to the API):
[
{
"id": "662907decf527b93",
"type": "function",
"z": "a9336bf7.8341c8",
"name": "Tweet with twitterApiV2",
"func": "const Twitter = twitterApiV2.default;\n\nconst client = new Twitter({\n appKey: 'API Key',\n appSecret: ' API Key Secret',\n accessToken: 'Access token',\n accessSecret: 'Access Token secret',\n});\nvar image_url = msg.url;\n\nvar tweet=msg.payload; //text coming from my payload\nvar buffer=msg.media //image buffer stored before in msg.media - call image url with http get node to get the buffer\n\n // First, post all your images to Twitter\n const mediaIds = await Promise.all([\n \n // using local file path\n //client.v1.uploadMedia(image_url),\n \n // using image as a buffer\n client.v1.uploadMedia(buffer, { type: 'png' }),\n\n ]);\n\n// Wrap the tweet posting logic inside an async function\n(async () => {\n try {\n const result = await client.v2.tweet({\n text: tweet,\n media: { media_ids: mediaIds }\n });\n msg.tweet_text = \"You successfully tweeted: \" + result.data.text;\n msg.result = result;\n node.send(msg);\n } catch (err) {\n msg.payload = \"Error: \" + JSON.stringify(err);\n node.send(msg);\n }\n})();\n\nreturn null;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [
{
"var": "twitterApiV2",
"module": "twitter-api-v2"
}
],
"x": 3370,
"y": 800,
"wires": [
[
"6a940578382929af",
"259d43ee8773b6e1"
]
]
},
{
"id": "bad44f1879819e79",
"type": "inject",
"z": "a9336bf7.8341c8",
"name": "",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"topic": "",
"payload": "",
"payloadType": "date",
"x": 3200,
"y": 620,
"wires": [
[
"662907decf527b93"
]
]
},
{
"id": "6a940578382929af",
"type": "debug",
"z": "a9336bf7.8341c8",
"name": "debug 6",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 3640,
"y": 740,
"wires": []
},
{
"id": "259d43ee8773b6e1",
"type": "debug",
"z": "a9336bf7.8341c8",
"name": "debug 7",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "tweet",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 3640,
"y": 860,
"wires": []
}
]