Serverless CampFireHousing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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