feat: Implement search tweets trigger

This commit is contained in:
Faruk AYDIN
2022-08-31 15:28:53 +03:00
committed by Ali BARIN
parent 81a444e056
commit abaad7cb82
6 changed files with 107 additions and 60 deletions

View File

@@ -0,0 +1,73 @@
import { IJSONObject } from '@automatisch/types';
import { URLSearchParams } from 'url';
import TwitterClient from '../index';
import omitBy from 'lodash/omitBy';
import isEmpty from 'lodash/isEmpty';
import qs from 'qs';
export default class SearchTweets {
client: TwitterClient;
constructor(client: TwitterClient) {
this.client = client;
}
async run(searchTerm: string, lastInternalId?: string) {
const token = {
key: this.client.connection.formattedData.accessToken as string,
secret: this.client.connection.formattedData.accessSecret as string,
};
let response;
const tweets: IJSONObject[] = [];
do {
const params: IJSONObject = {
query: searchTerm,
since_id: lastInternalId,
pagination_token: response?.data?.meta?.next_token,
};
const queryParams = qs.stringify(omitBy(params, isEmpty));
const requestPath = `/2/tweets/search/recent${
queryParams.toString() ? `?${queryParams.toString()}` : ''
}`;
const requestData = {
url: `${TwitterClient.baseUrl}${requestPath}`,
method: 'GET',
};
const authHeader = this.client.oauthClient.toHeader(
this.client.oauthClient.authorize(requestData, token)
);
response = await this.client.httpClient.get(requestPath, {
headers: { ...authHeader },
});
if (response.data.meta.result_count > 0) {
response.data.data.forEach((tweet: IJSONObject) => {
if (!lastInternalId || Number(tweet.id) > Number(lastInternalId)) {
tweets.push(tweet);
} else {
return;
}
});
}
} while (response.data.meta.next_token && lastInternalId);
if (response.data?.errors) {
const errorMessages = response.data.errors
.map((error: IJSONObject) => error.detail)
.join(' ');
throw new Error(
`Error occured while fetching user data: ${errorMessages}`
);
}
return tweets;
}
}

View File

@@ -8,6 +8,7 @@ import GetCurrentUser from './endpoints/get-current-user';
import GetUserByUsername from './endpoints/get-user-by-username';
import GetUserTweets from './endpoints/get-user-tweets';
import CreateTweet from './endpoints/create-tweet';
import SearchTweets from './endpoints/search-tweets';
export default class TwitterClient {
flow: IFlow;
@@ -22,6 +23,7 @@ export default class TwitterClient {
getUserByUsername: GetUserByUsername;
getUserTweets: GetUserTweets;
createTweet: CreateTweet;
searchTweets: SearchTweets;
static baseUrl = 'https://api.twitter.com';
@@ -54,5 +56,6 @@ export default class TwitterClient {
this.getUserByUsername = new GetUserByUsername(this);
this.getUserTweets = new GetUserTweets(this);
this.createTweet = new CreateTweet(this);
this.searchTweets = new SearchTweets(this);
}
}

View File

@@ -260,8 +260,8 @@
]
},
{
"name": "Search Tweet",
"key": "searchTweet",
"name": "Search Tweets",
"key": "searchTweets",
"description": "Will be triggered when any user tweet something containing a specific keyword, phrase, username or hashtag.",
"substeps": [
{

View File

@@ -1,12 +1,15 @@
import TwitterClient from './client';
import UserTweet from './triggers/user-tweet';
import SearchTweets from './triggers/search-tweets';
export default class Triggers {
client: TwitterClient;
userTweet: UserTweet;
searchTweets: SearchTweets;
constructor(client: TwitterClient) {
this.client = client;
this.userTweet = new UserTweet(client);
this.searchTweets = new SearchTweets(client);
}
}

View File

@@ -1,58 +0,0 @@
import TwitterApi, { TwitterApiTokens } from 'twitter-api-v2';
import { IJSONObject } from '@automatisch/types';
export default class SearchTweet {
client: TwitterApi;
parameters: IJSONObject;
constructor(connectionData: IJSONObject, parameters: IJSONObject) {
this.client = new TwitterApi({
appKey: connectionData.consumerKey,
appSecret: connectionData.consumerSecret,
accessToken: connectionData.accessToken,
accessSecret: connectionData.accessSecret,
} as TwitterApiTokens);
this.parameters = parameters;
}
async run(startTime: Date) {
const tweets = [];
const response = await this.client.v2.search(
this.parameters.searchTerm as string,
{
max_results: 50,
'tweet.fields': 'created_at',
}
);
for await (const tweet of response.data.data) {
if (new Date(tweet.created_at).getTime() <= startTime.getTime()) {
break;
}
tweets.push(tweet);
if (response.data.meta.next_token) {
await response.fetchNext();
}
}
return tweets;
}
async testRun() {
const response = await this.client.v2.search(
this.parameters.searchTerm as string,
{
max_results: 10,
'tweet.fields': 'created_at',
}
);
const mostRecentTweet = response.data.data[0];
return [mostRecentTweet];
}
}

View File

@@ -0,0 +1,26 @@
import TwitterClient from '../client';
export default class SearchTweets {
client: TwitterClient;
constructor(client: TwitterClient) {
this.client = client;
}
async run(lastInternalId: string) {
return this.getTweets(lastInternalId);
}
async testRun() {
return this.getTweets();
}
async getTweets(lastInternalId?: string) {
const tweets = await this.client.searchTweets.run(
this.client.step.parameters.searchTerm as string,
lastInternalId
);
return tweets;
}
}