From ce5a043fd417db1ecffa07ec6e3e77c5da1ee846 Mon Sep 17 00:00:00 2001 From: Ricardo Espinoza Date: Thu, 17 Sep 2020 17:02:23 -0400 Subject: [PATCH] :zap: Add retweet, reply and like operations (#964) --- .../nodes/Twitter/TweetDescription.ts | 113 +++++++++++++++++- .../nodes/Twitter/TweetInterface.ts | 1 + .../nodes-base/nodes/Twitter/Twitter.node.ts | 36 ++++++ 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/packages/nodes-base/nodes/Twitter/TweetDescription.ts b/packages/nodes-base/nodes/Twitter/TweetDescription.ts index 12cb87ebfe..7e32046127 100644 --- a/packages/nodes-base/nodes/Twitter/TweetDescription.ts +++ b/packages/nodes-base/nodes/Twitter/TweetDescription.ts @@ -18,13 +18,23 @@ export const tweetOperations = [ { name: 'Create', value: 'create', - description: 'Create a new tweet', + description: 'Create or reply a tweet', }, { name: 'Search', value: 'search', description: 'Search tweets', }, + { + name: 'Like', + value: 'like', + description: 'Like a tweet', + }, + { + name: 'Retweet', + value: 'retweet', + description: 'Retweet a tweet', + }, ], default: 'create', description: 'The operation to perform.', @@ -87,6 +97,13 @@ export const tweetFields = [ default: false, description: 'Whether or not to put a pin on the exact coordinates a Tweet has been sent from.', }, + { + displayName: 'In Reply to Tweet', + name: 'inReplyToStatusId', + type: 'string', + default: '', + description: 'The ID of an existing status that the update is in reply to.', + }, { displayName: 'Location', name: 'locationFieldsUi', @@ -321,4 +338,98 @@ export const tweetFields = [ }, ], }, +/* -------------------------------------------------------------------------- */ +/* tweet:like */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Tweet ID', + name: 'tweetId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + operation: [ + 'like', + ], + resource: [ + 'tweet', + ], + }, + }, + description: 'The ID of the tweet', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'like', + ], + resource: [ + 'tweet', + ], + }, + }, + options: [ + { + displayName: 'include Entities', + name: 'includeEntities', + type: 'boolean', + default: false, + description: 'The entities node will be omitted when set to false', + }, + ], + }, +/* -------------------------------------------------------------------------- */ +/* tweet:retweet */ +/* -------------------------------------------------------------------------- */ + { + displayName: 'Tweet ID', + name: 'tweetId', + type: 'string', + required: true, + default: '', + displayOptions: { + show: { + operation: [ + 'retweet', + ], + resource: [ + 'tweet', + ], + }, + }, + description: 'The ID of the tweet', + }, + { + displayName: 'Additional Fields', + name: 'additionalFields', + type: 'collection', + placeholder: 'Add Field', + default: {}, + displayOptions: { + show: { + operation: [ + 'retweet', + ], + resource: [ + 'tweet', + ], + }, + }, + options: [ + { + displayName: 'Trim User', + name: 'trimUser', + type: 'boolean', + default: false, + description: `When set to either true, each tweet returned in a timeline will include a user object including only the status authors numerical ID.`, + }, + ], + }, ] as INodeProperties[]; diff --git a/packages/nodes-base/nodes/Twitter/TweetInterface.ts b/packages/nodes-base/nodes/Twitter/TweetInterface.ts index 10b16d6a2d..564e92cc1b 100644 --- a/packages/nodes-base/nodes/Twitter/TweetInterface.ts +++ b/packages/nodes-base/nodes/Twitter/TweetInterface.ts @@ -5,4 +5,5 @@ export interface ITweet { media_ids?: string; possibly_sensitive?: boolean; status: string; + in_reply_to_status_id?: string; } diff --git a/packages/nodes-base/nodes/Twitter/Twitter.node.ts b/packages/nodes-base/nodes/Twitter/Twitter.node.ts index a62f9fd95b..bab8fd657e 100644 --- a/packages/nodes-base/nodes/Twitter/Twitter.node.ts +++ b/packages/nodes-base/nodes/Twitter/Twitter.node.ts @@ -28,6 +28,7 @@ import { import { ITweet, } from './TweetInterface'; +import { isDate } from 'util'; const ISO6391 = require('iso-639-1'); @@ -109,6 +110,10 @@ export class Twitter implements INodeType { status: text, }; + if (additionalFields.inReplyToStatusId) { + body.in_reply_to_status_id = additionalFields.inReplyToStatusId as string; + } + if (additionalFields.attachments) { const mediaIds = []; const attachments = additionalFields.attachments as string; @@ -225,6 +230,7 @@ export class Twitter implements INodeType { } } + console.log(body); responseData = await twitterApiRequest.call(this, 'POST', '/statuses/update.json', body); } // https://developer.twitter.com/en/docs/tweets/search/api-reference/get-search-tweets @@ -268,6 +274,36 @@ export class Twitter implements INodeType { responseData = responseData.statuses; } } + //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-favorites-create + if (operation === 'like') { + const tweetId = this.getNodeParameter('tweetId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const qs: IDataObject = { + id: tweetId, + }; + + if (additionalFields.includeEntities) { + qs.include_entities = additionalFields.includeEntities as boolean; + } + + responseData = await twitterApiRequest.call(this, 'POST', '/favorites/create.json', {}, qs); + } + //https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-retweet-id + if (operation === 'retweet') { + const tweetId = this.getNodeParameter('tweetId', i) as string; + const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; + + const qs: IDataObject = { + id: tweetId, + }; + + if (additionalFields.trimUser) { + qs.trim_user = additionalFields.trimUser as boolean; + } + + responseData = await twitterApiRequest.call(this, 'POST', `/statuses/retweet/${tweetId}.json`, {}, qs); + } } if (Array.isArray(responseData)) { returnData.push.apply(returnData, responseData as IDataObject[]);