Skip to content

Commit

Permalink
module updates, cleanup and organization
Browse files Browse the repository at this point in the history
  • Loading branch information
Wesley LeMahieu committed Oct 16, 2022
1 parent 7faa46f commit 9c5828f
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 65 deletions.
13 changes: 7 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"license": "MIT",
"dependencies": {
"@google-cloud/functions-framework": "^3.1.2",
"axios": "^0.27.2"
"axios": "^1.1.0"
},
"scripts": {
"start": "functions-framework --source=build/src/ --target=run --port=8088",
Expand All @@ -21,12 +21,13 @@
"posttest": "npm run lint"
},
"devDependencies": {
"@types/express": "^4.17.13",
"@types/node": "^14.11.2",
"@types/axios": "^0.14.0",
"@types/express": "^4.17.14",
"@types/node": "^18.11.0",
"@types/node-fetch": "^2.6.2",
"concurrently": "^7.2.2",
"gts": "^3.1.0",
"nodemon": "^2.0.18",
"typescript": "^4.0.3"
"gts": "^3.1.1",
"nodemon": "^2.0.20",
"typescript": "^4.8.4"
}
}
37 changes: 37 additions & 0 deletions src/api/getTweets.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* getTweets.ts
*
* /2/users/:id/tweets
*
* Returns a list of tweets while considering pagination
*/
import get from '../helpers/get';

interface ReturnI {
newNextToken?: string;
tweets: Array<any>;
}

type GetTweetsT = (
myUserId: string,
perPage: number,
nextToken?: string
) => Promise<ReturnI>;

const getTweets: GetTweetsT = async (myUserId, perPage, nextToken) => {
let url = `https://api.twitter.com/2/users/${myUserId}/tweets?tweet.fields=entities&max_results=${perPage}`;

// if there is another page, we'll have a token
if (nextToken?.length) {
url = `${url}&pagination_token=${nextToken}`;
}

// collect tweets
const results = await get(url);
const tweets = results?.data?.data;
const newNextToken = results?.data?.meta?.next_token;

return {newNextToken, tweets};
};

export default getTweets;
15 changes: 15 additions & 0 deletions src/api/getUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* getUser.ts
*
* /2/users/by/username/:id
*
* Returns a particular user's info
*/
import get from '../helpers/get';

const getUser = async (username: string) => {
const url = `https://api.twitter.com/2/users/by/username/${username}`;
return get(url);
};

export default getUser;
16 changes: 16 additions & 0 deletions src/helpers/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* get.ts
*
* GET endpoint using bearer token authorization
*/
import axios from 'axios';

const get = async (url: string) => {
return axios.get(url, {
headers: {
Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
},
});
};

export default get;
87 changes: 28 additions & 59 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,75 +1,44 @@
/**
* index.ts
*
* This Google Cloud Function will connect to Twitter using
* the provided Twitter Bearer token stored inside of Cloud
* secrets and allow you to use the Twitter API!
*
* Example #1 fetches the 20th Tweet ever recorded in history but @jack
* Example #2 lists all of your own Tweets using tail-call recursion
* This example lists all Tweets for the provider username using tail-call recursion.
*/
import type {HttpFunction} from '@google-cloud/functions-framework/build/src/functions';
import axios from 'axios';

const getTweets = async (
myUserId: string,
perPage: number,
nextToken?: string
) => {
let url = `https://api.twitter.com/2/users/${myUserId}/tweets?tweet.fields=entities&max_results=${perPage}`;
if (nextToken?.length) {
url = `${url}&pagination_token=${nextToken}`;
}

const results = await axios.get(url, {
headers: {
Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
},
});
import type {HttpFunction} from '@google-cloud/functions-framework/build/src/functions';
import getUser from './api/getUser';
import getTweets from './api/getTweets';

// collect tweets
const tweets = results?.data?.data;
const newNextToken = results?.data?.meta?.next_token;

return {newNextToken, tweets};
};
const twitterUsername = 'wesleylemahieu';

export const run: HttpFunction = async (req, res) => {
console.log('Connecting to Twitter API...');

// allow our local apps to interact with this gcf. (affects local only)
res.set('Access-Control-Allow-Origin', '*');

const {nextToken, rowsPerPage} = req.query;

console.log({nextToken, rowsPerPage});
try {
console.log('Fetching all my tweets...');
const myUser = await axios.get(
'https://api.twitter.com/2/users/by/username/WesleyLeMahieu',
{
headers: {
Authorization: `Bearer ${process.env.TWITTER_BEARER_TOKEN}`,
},
}
);
const rowsPerPage = parseInt((req.query.rowsPerPage as string) || '100', 10);
const nextToken = req.query.nextToken as string;

const myUserId = myUser.data?.data?.id;
const response = await getUser(twitterUsername);
const myUserId = response?.data?.data?.id;

if (myUserId) {
// const likes = await client.tweets.usersIdLikedTweets(myUser.data.id);
const {newNextToken, tweets} = await getTweets(
myUserId,
parseInt((rowsPerPage as string) || '100', 0),
(nextToken as string) || ''
);
res.send({
// likes: likes?.data,
nextToken: newNextToken,
tweets,
});
} else {
res.send('No user found, check your Twitter secrets!');
}
} catch (e) {
console.log(e);
if (!response?.data?.data?.id) {
throw {
status: 400,
message: 'No user found, check your Twitter secrets!',
};
}

const {newNextToken, tweets} = await getTweets(
myUserId,
rowsPerPage,
nextToken
);

res.send({
// likes: likes?.data,
nextToken: newNextToken,
tweets,
});
};

0 comments on commit 9c5828f

Please sign in to comment.