Skip to content

Instantly share code, notes, and snippets.

@ecwyne
Last active July 23, 2019 08:05
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ecwyne/0438408804cd6e1023ba381c4cb5efc9 to your computer and use it in GitHub Desktop.
Save ecwyne/0438408804cd6e1023ba381c4cb5efc9 to your computer and use it in GitHub Desktop.
Serverless CampFireHousing
import fetch from 'node-fetch';
import Twitter from 'twit';
import { parse, format } from 'fecha';
import { take } from 'ramda';
const URL = 'GOOGLE_SHEETS_URL';
const T = new Twitter({
consumer_key: 'consumer_key',
consumer_secret: 'consumer_secret',
access_token: 'access_token',
access_token_secret: 'access_token_secret'
});
// convert Google sheets date string to javascript Date object
const cellToDate = (str: string): Date =>
parse(`${str} -0500`, 'MM/DD/YYYY HH:mm:ss ZZ') as Date;
const formatDate = (d: Date): string => format(d, 'MMM Do @ h:mm:ssA');
const parseDate = (str: string): Date =>
parse(`${str} -0800`, 'MMM Do @ h:mm:ssA ZZ') as Date;
// Generate text for status
const postToStatus = (post: any): string =>
shorten(`Posted: ${formatDate(cellToDate(post.gsx$submittedon.$t))}
${post.gsx$beds.$t} bed/${post.gsx$baths.$t} bath
Price: ${post.gsx$price.$t}
City: ${post.gsx$city.$t}
Term: ${post.gsx$lengthofhousing.$t}
Available: ${post.gsx$availability.$t}
Pets: ${post.gsx$pets.$t}
Description: ${post.gsx$typeofhousing.$t}`);
// Limit tweet length to 280
const shorten = (str: string): string =>
str.length < 280 ? str : take(277, str) + '...';
export const tweet = async () => {
// All postings
const arr = await fetch(URL)
.then(r => r.json())
.then(obj => obj.feed.entry);
// Date of most recent tweeted post
const previousDate = await T.get('statuses/user_timeline', {
count: 1
})
.then((r: any) => r.data[0].text.split('\n')[0].replace('Posted: ', ''))
.then(parseDate)
.then(res => res || new Date('2018-11-17'))
.catch(() => new Date('2018-11-10'));
// Postings added since last tweet
const newPostings = arr.filter(
(post: any) =>
post.gsx$submittedon.$t &&
cellToDate(post.gsx$submittedon.$t) > previousDate
);
// tweet each new posting
for (const post of newPostings) {
const status = postToStatus(post);
await T.post('statuses/update', { status })
.then((res: any) => console.log(res.data.id))
.catch((err: Error) => console.log(err.message));
console.log('\n', status);
}
};
service:
name: camp-fire-housing
plugins:
- serverless-plugin-typescript
provider:
name: aws
region: us-west-2
stage: prod
runtime: nodejs8.10
environment:
TZ: America/Los_Angeles
functions:
tweet:
handler: handler.tweet
timeout: 120
events:
- schedule: rate(5 minutes)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment