mirror of
https://codeberg.org/SafeTwitch/safetwitch-backend.git
synced 2024-12-31 18:13:55 -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;
|
||||
if (cursor) {
|
||||
discoveryData = await twitch.getDirectory(15, cursor)
|
||||
.catch(next)
|
||||
} else {
|
||||
discoveryData = await twitch.getDirectory(15)
|
||||
.catch(next)
|
||||
}
|
||||
|
||||
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
|
|
@ -5,7 +5,7 @@ export interface Category {
|
|||
displayName: string
|
||||
viewers: number
|
||||
tags: Tag[]
|
||||
createdAt: Date
|
||||
cursor: string
|
||||
createdAt?: Date
|
||||
cursor?: string
|
||||
image: string
|
||||
}
|
|
@ -17,13 +17,12 @@ export interface StreamData {
|
|||
export interface StreamerData {
|
||||
username: string
|
||||
followers: number
|
||||
followersAbbv: string
|
||||
isLive: boolean
|
||||
about: string
|
||||
socials?: Social[]
|
||||
pfp: string
|
||||
stream?: StreamData | null
|
||||
isPartner: boolean
|
||||
isPartner: boolean | null
|
||||
colorHex: string
|
||||
id: number
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ export const errorHandler = (err: Error, req: Request, res: Response, next: Next
|
|||
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() { }
|
||||
|
||||
/**
|
||||
* Gets information about a streamer, like socials, about, and more.
|
||||
* @see StreamerData
|
||||
|
@ -147,7 +146,6 @@ export class TwitchAPI {
|
|||
socials: socials as Social[],
|
||||
isLive: (!!parsedStream),
|
||||
isPartner: rawStreamerData.user.isPartner,
|
||||
followersAbbv: abbreviatedFollowers,
|
||||
colorHex: '#' + rawStreamerData.user.primaryColorHex,
|
||||
id: Number(rawStreamerData.user.id),
|
||||
stream: parsedStream
|
||||
|
@ -509,4 +507,81 @@ export class TwitchAPI {
|
|||
|
||||
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