monorepo/services/services/youtube.service.ts

85 lines
2.6 KiB
TypeScript

'use strict'
import { youtube_v3 } from 'googleapis'
import { Context, Service, ServiceBroker, ServiceSchema } from 'moleculer'
import GoogleServices from '../mixins/google.mixin'
import { FeedResponse, FeedResult } from '../types/feed'
import { ApiMeta } from '../types/meta'
export default class YoutubeService extends Service {
private google = new GoogleServices().google
private channels: [channel: string, id: string][] = [
['Red Plateaus', 'UCsln1E-ttrNPsMivrnf9V7w'],
['Zoe Baker', 'UC3FD64RRsrCLpiZNkq7ZkSg'],
['Jonas Ceika,', 'UCSkzHxIcfoEr69MWBdo0ppg'],
['Radical Reviewer', 'UC_V9wKk1Dd2rpZ4fxj7pKXA'],
['donoteat01', 'UCFdazs-6CNzSVv1J0a-qy4A'],
['Contra', 'UCNvsIonJdJ5E4EXMa65VYpA'],
['Shaun', 'UCJ6o36XL0CpYb6U5dNBiXHQ'],
['hbomb', 'UClt01z1wHHT7c5lKcU8pxRQ'],
['Philo tube', 'UC2PA-AKmVpU6NKCGtZq_rKQ'],
['anark', 'UC1CjJYTUeor8EUFsbgwu5TQ']
]
// @ts-ignore
public constructor (public broker: ServiceBroker, schema: ServiceSchema<{}> = {}) {
super(broker)
this.parseServiceSchema(Service.mergeSchemas({
name: 'youtube',
actions: {
/**
* Get aggregate feed
*
*/
feed: {
cache: true,
rest: {
method: 'GET',
path: '/feed',
},
async handler (this: YoutubeService, ctx: Context<{}, ApiMeta>): Promise<FeedResponse> {
return this.GetAggregatedFeed()
}
}
}
}, schema))
}
public async GetAggregatedFeed (): Promise<FeedResponse> {
const onlyVideos = (item: youtube_v3.Schema$Activity) => item.snippet.type === 'upload'
return (await Promise.all(
this.channels.map(([channel, id]) => this.GetActivities(id))
))
.flatMap(response => response.data.items)
.filter(onlyVideos)
.map(item => this.PickActivityProperties(item))
}
private GetActivities (channelId: string) {
return this.google.youtube('v3').activities.list({
channelId,
part: ['snippet', 'contentDetails'],
maxResults: 1000
})
}
private PickBestThumbnail (thumbnails: youtube_v3.Schema$ThumbnailDetails) {
return String(Object.values(thumbnails).sort((a, b) => b.width - a.width)[0].url).split('/').pop()
/* https://i.ytimg.com/vi/${id}/${thumbnail} */
}
private PickActivityProperties (activity: youtube_v3.Schema$Activity): FeedResult {
return {
title: activity.snippet.title,
id: activity.contentDetails.upload.videoId,
description: activity.snippet.description?.substring(0, 127).split('\n')[0],
thumbnail: this.PickBestThumbnail(activity.snippet.thumbnails),
channel: activity.snippet.channelId,
date: new Date(activity.snippet.publishedAt).valueOf()
}
}
}