Created
June 20, 2019 20:57
-
-
Save shrugs/ce1f2e37b0bde295d26d3114e8974a28 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 AWS = require("aws-sdk"); | |
import got = require("got"); | |
import { | |
Context, | |
DynamoDBStreamEvent, | |
StreamRecord, | |
AttributeValue, | |
} from "aws-lambda"; | |
import { uniq, keyBy } from "lodash"; | |
import { LiveChannelRecord } from "./util/types"; | |
import { getKnownChannelInfos } from "./util/channelInfo"; | |
const kTwitchPurpleInDecimal = 7506394; | |
const kViewCountThreshold = 5000; | |
const kWebhook = "{your discord webhook url}"; | |
const executeWebhook = async (webhook: string, body): Promise<void> => { | |
await got.post(webhook, { | |
json: true, | |
body, | |
}); | |
}; | |
/** | |
* Called by DynamoDB Stream | |
* On newly live users, publish a notification to discord. | |
*/ | |
export const handler = main( | |
async (event: DynamoDBStreamEvent, context: Context): Promise<any> => { | |
// build `LiveChannelRecord`s from INSERT operations | |
const inserts = event.Records.filter(r => r.eventName === "INSERT") | |
.map(r => r.dynamodb) | |
.filter((d): d is StreamRecord => !!d) | |
.map(d => d.NewImage) | |
.filter((i): i is { [_: string]: AttributeValue } => !!i) | |
.map( | |
item => AWS.DynamoDB.Converter.unmarshall(item) as LiveChannelRecord, | |
); | |
if (inserts.length === 0) { | |
return; | |
} | |
const ids = uniq(inserts.map(image => image.id)); | |
console.log(`fetching ids: ${ids}`); | |
const infoById = keyBy( | |
await getKnownChannelInfos(ids, ["id", "login"]), | |
"id", | |
); | |
const messages = inserts | |
.filter(image => !!infoById[image.id]) | |
// ^ filter only people we have information about | |
.filter(image => { | |
try { | |
const count = parseInt(image.view_count, 10); | |
return count > kViewCountThreshold; | |
} catch { | |
return false; | |
} | |
}) | |
// ^ filter by view_count | |
.map(async image => { | |
console.log( | |
`Posting Notification: ${image.id}/${image.username} went live (${ | |
image.game | |
})`, | |
); | |
const { login } = infoById[image.id]; | |
const url = `https://twitch.tv/${login}`; | |
// NOTE: don't have to worry about throwing because of filter above | |
const viewCount = parseInt(image.view_count, 10).toLocaleString(); | |
await executeWebhook(kWebhook, { | |
content: `${image.username} is live with Stickers`, | |
embeds: [ | |
{ | |
author: { name: image.username }, | |
color: kTwitchPurpleInDecimal, | |
title: image.title, | |
url, | |
fields: [ | |
{ | |
name: "Playing", | |
value: image.game, | |
inline: true, | |
}, | |
{ | |
name: "View Count", | |
value: viewCount, | |
inline: true, | |
}, | |
], | |
image: { | |
url: `https://static-cdn.jtvnw.net/previews-ttv/live_user_${login}-1280x720.jpg`, | |
}, | |
}, | |
], | |
}); | |
}); | |
await Promise.all(messages); | |
}, | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment