mirror of
https://codeberg.org/SafeTwitch/safetwitch-backend.git
synced 2025-01-03 11:20:08 -05:00
Add search endpoint
This commit is contained in:
parent
65a6c62b38
commit
7bf75fa99e
5 changed files with 559 additions and 467 deletions
|
@ -23,8 +23,10 @@ profileRouter.get('/discover', async (req, res, next) => {
|
||||||
let discoveryData;
|
let discoveryData;
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
discoveryData = await twitch.getDirectory(15, cursor)
|
discoveryData = await twitch.getDirectory(15, cursor)
|
||||||
|
.catch(next)
|
||||||
} else {
|
} else {
|
||||||
discoveryData = await twitch.getDirectory(15)
|
discoveryData = await twitch.getDirectory(15)
|
||||||
|
.catch(next)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
|
@ -69,4 +71,20 @@ profileRouter.get('/badges', async (req, res, next) => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
profileRouter.get('/search', async (req, res, next) => {
|
||||||
|
const query = req.query.query
|
||||||
|
if(!query)
|
||||||
|
return res.status(400).send({
|
||||||
|
status: 'error',
|
||||||
|
message: 'No query provided'
|
||||||
|
})
|
||||||
|
|
||||||
|
const result = await twitch.getSearchResult(query.toString())
|
||||||
|
.catch(next)
|
||||||
|
res.send({
|
||||||
|
status: 'ok',
|
||||||
|
data: result
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
export default profileRouter
|
export default profileRouter
|
|
@ -5,7 +5,7 @@ export interface Category {
|
||||||
displayName: string
|
displayName: string
|
||||||
viewers: number
|
viewers: number
|
||||||
tags: Tag[]
|
tags: Tag[]
|
||||||
createdAt: Date
|
createdAt?: Date
|
||||||
cursor: string
|
cursor?: string
|
||||||
image: string
|
image: string
|
||||||
}
|
}
|
|
@ -17,13 +17,12 @@ export interface StreamData {
|
||||||
export interface StreamerData {
|
export interface StreamerData {
|
||||||
username: string
|
username: string
|
||||||
followers: number
|
followers: number
|
||||||
followersAbbv: string
|
|
||||||
isLive: boolean
|
isLive: boolean
|
||||||
about: string
|
about: string
|
||||||
socials?: Social[]
|
socials?: Social[]
|
||||||
pfp: string
|
pfp: string
|
||||||
stream?: StreamData | null
|
stream?: StreamData | null
|
||||||
isPartner: boolean
|
isPartner: boolean | null
|
||||||
colorHex: string
|
colorHex: string
|
||||||
id: number
|
id: number
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,5 @@ export const errorHandler = (err: Error, req: Request, res: Response, next: Next
|
||||||
return next(err)
|
return next(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(500).send({ status: 'error', message: err.message})
|
res.status(500).send({ status: 'error', message: err})
|
||||||
}
|
}
|
|
@ -17,7 +17,6 @@ export class TwitchAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets information about a streamer, like socials, about, and more.
|
* Gets information about a streamer, like socials, about, and more.
|
||||||
* @see StreamerData
|
* @see StreamerData
|
||||||
|
@ -147,7 +146,6 @@ export class TwitchAPI {
|
||||||
socials: socials as Social[],
|
socials: socials as Social[],
|
||||||
isLive: (!!parsedStream),
|
isLive: (!!parsedStream),
|
||||||
isPartner: rawStreamerData.user.isPartner,
|
isPartner: rawStreamerData.user.isPartner,
|
||||||
followersAbbv: abbreviatedFollowers,
|
|
||||||
colorHex: '#' + rawStreamerData.user.primaryColorHex,
|
colorHex: '#' + rawStreamerData.user.primaryColorHex,
|
||||||
id: Number(rawStreamerData.user.id),
|
id: Number(rawStreamerData.user.id),
|
||||||
stream: parsedStream
|
stream: parsedStream
|
||||||
|
@ -509,4 +507,81 @@ export class TwitchAPI {
|
||||||
|
|
||||||
return formatedBadges
|
return formatedBadges
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSearchResult = async (query: string) => {
|
||||||
|
const payload = {
|
||||||
|
"operationName": "SearchResultsPage_SearchResults",
|
||||||
|
"variables": {
|
||||||
|
"query": query,
|
||||||
|
"options": null,
|
||||||
|
"requestID": "75948144-d051-4203-8511-57f3ee9b809a"
|
||||||
|
},
|
||||||
|
"extensions": {
|
||||||
|
"persistedQuery": {
|
||||||
|
"version": 1,
|
||||||
|
"sha256Hash": "6ea6e6f66006485e41dbe3ebd69d5674c5b22896ce7b595d7fce6411a3790138"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(this.twitchUrl, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
headers: this.headers
|
||||||
|
})
|
||||||
|
const data = await res.json()
|
||||||
|
const resultsData = data.data.searchFor
|
||||||
|
|
||||||
|
const formattedStreamers: StreamerData[] = resultsData.channels.edges.map((data: any) => {
|
||||||
|
return {
|
||||||
|
username: data.item.login,
|
||||||
|
followers: data.item.followers.totalCount,
|
||||||
|
isLive: !(data.item.stream === null),
|
||||||
|
about: data.item.description,
|
||||||
|
pfp: `${process.env.URL}/proxy/img/${base64(data.item.profileImageURL)}`,
|
||||||
|
isPartner: null,
|
||||||
|
colorHex: '#fff',
|
||||||
|
id: Number(data.item.channel.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const foundCategories: Category[] = []
|
||||||
|
for (let category of resultsData.games.edges) {
|
||||||
|
let tags = category.item.tags.map((data: { tagName: string }) => {
|
||||||
|
return data.tagName
|
||||||
|
})
|
||||||
|
|
||||||
|
foundCategories.push({
|
||||||
|
name: category.item.name,
|
||||||
|
displayName: category.item.displayName,
|
||||||
|
viewers: category.item.viewersCount,
|
||||||
|
tags,
|
||||||
|
image: category.item.boxArtURL,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundRelatedLiveChannels: StreamData[] = await Promise.all(resultsData.relatedLiveChannels.edges.map(async (data: any) => {
|
||||||
|
return await this.getStreamerInfo(data.item.stream.broadcaster.login)
|
||||||
|
}))
|
||||||
|
|
||||||
|
const foundChannelsWithTag: StreamData[] = resultsData.channelsWithTag.edges.map((data: any) => {
|
||||||
|
return {
|
||||||
|
username: data.item.login,
|
||||||
|
followers: data.item.followers.totalCount,
|
||||||
|
isLive: !(data.item.stream === null),
|
||||||
|
about: data.item.description,
|
||||||
|
pfp: `${process.env.URL}/proxy/img/${base64(data.item.profileImageURL)}`,
|
||||||
|
isPartner: null,
|
||||||
|
colorHex: '#fff',
|
||||||
|
id: Number(data.item.channel.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
channels: formattedStreamers,
|
||||||
|
categories: foundCategories,
|
||||||
|
relatedChannels: foundRelatedLiveChannels,
|
||||||
|
channelsWithTag: foundChannelsWithTag
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue