condense API routes in meantime

This commit is contained in:
3zachm 2023-01-23 00:36:04 -08:00
parent c31db440db
commit 6938983444
9 changed files with 148 additions and 231 deletions

View file

@ -1,33 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { createRedisInstance } from "../../../misc/redis";
import { getChannelEmotes, getGlobalEmotes } from "../../../misc/7TVAPI";
type Data = {
[key: string]: any;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const redis = createRedisInstance();
if (!redis) {
res
.status(500)
.json({ error: { message: "Internal API is down", code: 50000 } });
return;
}
try {
const channel = req.query.c
? await getChannelEmotes(redis, req.query.c as string)
: undefined;
const global = await getGlobalEmotes(redis);
redis.quit();
res.status(200).json({ channel, global });
} catch (e) {
console.log(e);
res
.status(500)
.json({ error: { message: "7TV or internal API is down", code: 10000 } });
}
}

View file

@ -1,34 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { createRedisInstance } from "../../../misc/redis";
import { getUserByID, getGlobalEmotes } from "../../../misc/BTTVAPI";
type Data = {
[key: string]: any;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const redis = createRedisInstance();
if (!redis) {
res.status(500).json({
error: { message: "Internal API is down", code: 50200 },
});
return;
}
try {
const channel = req.query.c
? (await getUserByID(redis, req.query.c as string)).channelEmotes
: undefined;
const global = await getGlobalEmotes(redis);
redis.quit();
res.status(200).json({ channel, global });
} catch (e) {
console.log(e);
res.status(500).json({
error: { message: "BTTV or internal API is down", code: 10200 },
});
}
}

78
pages/api/emotes.ts Normal file
View file

@ -0,0 +1,78 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { createRedisInstance } from "../../misc/redis";
import {
getGlobalEmotes as get7TVGlobalEmotes,
getChannelEmotes as get7TVChannelEmotes,
} from "../../misc/7TVAPI";
import {
getGlobalEmotes as getBTTVGlobalEmotes,
getUserByID as getBTTVUser,
} from "../../misc/BTTVAPI";
import {
getGlobalEmotes as getFFZGlobalEmotes,
getEmoteSet as getFFZEmoteSet,
} from "../../misc/FFZAPI";
import {
getGlobalEmotes as getTwitchGlobalEmotes,
getChannelEmotes as getTwitchChannelEmotes,
} from "../../misc/TwitchAPI";
type Data = {
[key: string]: any;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const redis = createRedisInstance();
if (!redis) {
res
.status(500)
.json({ error: { message: "Internal API is down", code: 50000 } });
return;
}
try {
const cachedJSON = await redis.get("ALL_EMOTES");
if (cachedJSON) {
const jsonRes = JSON.parse(cachedJSON);
redis.quit();
res.status(200).json(jsonRes);
return;
}
const ffzGlobal = await getFFZGlobalEmotes(redis);
const jsonRes = {
"7tv": {
global: (await get7TVGlobalEmotes(redis)).namedEmoteSet.emotes,
channel: (await get7TVChannelEmotes(redis, "61ad997effa9aba101bcfddf"))
.user.emote_sets[0].emotes,
},
bttv: {
global: await getBTTVGlobalEmotes(redis),
channel: (await getBTTVUser(redis, "56418014")).channelEmotes,
},
ffz: {
global: ffzGlobal.sets["3"].emoticons.concat(
ffzGlobal.sets["4330"].emoticons
),
channel: (await getFFZEmoteSet(redis, "341402")).set.emoticons,
},
twitch: {
global: (await getTwitchGlobalEmotes(redis)).data,
channel: (await getTwitchChannelEmotes(redis, "56418014")).data,
},
};
// cache emotelist for 20 minutes
await redis.set("ALL_EMOTES", JSON.stringify(jsonRes), "EX", 1200);
redis.quit();
res.status(200).json(jsonRes);
} catch (e) {
console.log(e);
res
.status(500)
.json({ error: { message: "Internal Emote API error", code: 10000 } });
}
}

View file

@ -120,7 +120,7 @@ export default async function handler(
interface asset { interface asset {
name: string; name: string;
count: number; count: number;
provider: "7tv" | "bttv" | "ffz" | "ttv"; provider: "7tv" | "bttv" | "ffz" | "twitch";
} }
interface fakeDataEntry { interface fakeDataEntry {
id: number; id: number;
@ -191,7 +191,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfSigh", name: "annytfSigh",
count: 1, count: 1,
provider: "ttv", provider: "twitch",
}, },
{ {
name: "GabeN", name: "GabeN",
@ -236,7 +236,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfHeart", name: "annytfHeart",
count: 98, count: 98,
provider: "ttv", provider: "twitch",
}, },
{ {
name: "Catge", name: "Catge",
@ -281,7 +281,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfRave", name: "annytfRave",
count: 5, count: 5,
provider: "ttv", provider: "twitch",
}, },
], ],
badges: [adminBadge, botDevBadge], badges: [adminBadge, botDevBadge],
@ -316,7 +316,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfMelt", name: "annytfMelt",
count: 16, count: 16,
provider: "ttv", provider: "twitch",
}, },
], ],
badges: [CEOBadge, adminBadge], badges: [CEOBadge, adminBadge],
@ -356,7 +356,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfAngy", name: "annytfAngy",
count: 90, count: 90,
provider: "ttv", provider: "twitch",
}, },
], ],
badges: [adminBadge, botDevBadge], badges: [adminBadge, botDevBadge],
@ -420,7 +420,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfHug", name: "annytfHug",
count: 19, count: 19,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -439,7 +439,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfLUL", name: "annytfLUL",
count: 9, count: 9,
provider: "ttv", provider: "twitch",
}, },
{ {
name: "peepoSnow", name: "peepoSnow",
@ -493,7 +493,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfPain", name: "annytfPain",
count: 37, count: 37,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -532,7 +532,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfKnuckles", name: "annytfKnuckles",
count: 2, count: 2,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -571,7 +571,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfCheer", name: "annytfCheer",
count: 54, count: 54,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -610,7 +610,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfBonk", name: "annytfBonk",
count: 77, count: 77,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -654,7 +654,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfSit", name: "annytfSit",
count: 53, count: 53,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -717,7 +717,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfGamba", name: "annytfGamba",
count: 32, count: 32,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -751,7 +751,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfFlower", name: "annytfFlower",
count: 33, count: 33,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -785,7 +785,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfFlower", name: "annytfFlower",
count: 79, count: 79,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -819,7 +819,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfSad", name: "annytfSad",
count: 2, count: 2,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },
@ -853,7 +853,7 @@ const fakeData: fakeDataEntry[] = [
{ {
name: "annytfHeart", name: "annytfHeart",
count: 63, count: 63,
provider: "ttv", provider: "twitch",
}, },
], ],
}, },

View file

@ -1,36 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { createRedisInstance } from "../../../misc/redis";
import { getEmoteSet, getGlobalEmotes } from "../../../misc/FFZAPI";
type Data = {
[key: string]: any;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const redis = createRedisInstance();
if (!redis) {
res.status(500).json({
error: { message: "Internal API is down", code: 50300 },
});
return;
}
try {
const channel = req.query.s
? (await getEmoteSet(redis, req.query.s as string)).set.emoticons
: undefined;
let global = await getGlobalEmotes(redis);
// set global emotes to be the three sets within the global object ("3", "4330")
global = global.sets["3"].emoticons.concat(global.sets["4330"].emoticons);
redis.quit();
res.status(200).json({ channel, global });
} catch (e) {
console.log(e);
res
.status(500)
.json({ error: { message: "FFZ or internal API is down", code: 10300 } });
}
}

View file

@ -1,34 +0,0 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { createRedisInstance } from "../../../misc/redis";
import { getChannelEmotes, getGlobalEmotes } from "../../../misc/TwitchAPI";
type Data = {
[key: string]: any;
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<Data>
) {
const redis = createRedisInstance();
if (!redis) {
res.status(500).json({
error: { message: "Internal API is down", code: 50100 },
});
return;
}
try {
const channel = req.query.c
? (await getChannelEmotes(redis, req.query.c as string)).data
: undefined;
const global = (await getGlobalEmotes(redis)).data;
redis.quit();
res.status(200).json({ channel, global });
} catch (e) {
console.log(e);
res.status(500).json({
error: { message: "Twitch or internal API is down", code: 10100 },
});
}
}

View file

@ -6,12 +6,11 @@ import Image from "next/image";
import Head from "next/head"; import Head from "next/head";
function Home() { function Home() {
let api7tvEmotes = `/api/7tv/emotes?c=61ad997effa9aba101bcfddf`;
const [emotesUrls, setEmotes] = useState([]); const [emotesUrls, setEmotes] = useState([]);
const [currentEmote, setCurrentEmote] = useState(0); const [currentEmote, setCurrentEmote] = useState(0);
useEffect(() => { useEffect(() => {
fetch(api7tvEmotes) fetch("/api/emotes")
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
// if error, return // if error, return
@ -19,19 +18,16 @@ function Home() {
return; return;
} }
// get all emote URLs // get all emote URLs
let emoteUrls = data.channel.user.emote_sets[0].emotes.map( let emoteUrls = data["7tv"].channel.map((emote: any) => {
(emote: any) => { let base_url = emote.data.host.url;
let base_url = emote.data.host.url; // get the largest emote size, append it to the base url
// get the largest emote size, append it to the base url let largest = emote.data.host.files[emote.data.host.files.length - 1];
let largest = // if width != height, skip it
emote.data.host.files[emote.data.host.files.length - 1]; if (largest.width !== largest.height) {
// if width != height, skip it return null;
if (largest.width !== largest.height) {
return null;
}
return `https:${base_url}/${largest.name}`;
} }
); return `https:${base_url}/${largest.name}`;
});
// remove null values // remove null values

View file

@ -6,7 +6,13 @@ import DashLayout from "../../../layouts/DashLayout";
import Image from "next/image"; import Image from "next/image";
import Loading from "../../../components/common/Loading"; import Loading from "../../../components/common/Loading";
// TODO: Animations interface EmoteURLs {
"7tv": { [key: string]: string };
bttv: { [key: string]: string };
ffz: { [key: string]: string };
twitch: { [key: string]: string };
[key: string]: { [key: string]: string };
}
function UserPage() { function UserPage() {
const [channelEmotes, setChannelEmotes] = useState<{ const [channelEmotes, setChannelEmotes] = useState<{
@ -20,7 +26,7 @@ function UserPage() {
useEffect(() => { useEffect(() => {
if (!router.isReady) return; if (!router.isReady) return;
fetch("/api/7tv/emotes?c=61ad997effa9aba101bcfddf") fetch("/api/emotes")
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
// if error, return // if error, return
@ -28,83 +34,59 @@ function UserPage() {
setErrorCode(data.error.code); setErrorCode(data.error.code);
return; return;
} }
// construct js object with emote names as keys and emote urls as values // construct js object with emote names as keys and emote urls for each provider
let emotes: { [key: string]: string } = {}; // 7tv
data.channel.user.emote_sets[0].emotes.forEach((emote: any) => { let emotes: EmoteURLs = { "7tv": {}, bttv: {}, ffz: {}, twitch: {} };
data["7tv"].channel.forEach((emote: any) => {
let base_url = emote.data.host.url; let base_url = emote.data.host.url;
// get the largest emote size, append it to the base url // get the largest emote size, append it to the base url
let largest = emote.data.host.files[emote.data.host.files.length - 1]; let largest = emote.data.host.files[emote.data.host.files.length - 1];
emotes[emote.data.name] = `https:${base_url}/${largest.name}`; emotes["7tv"][emote.data.name] = `https:${base_url}/${largest.name}`;
}); });
// same for global emotes // same for global emotes
data.global.namedEmoteSet.emotes.forEach((emote: any) => { data["7tv"].global.forEach((emote: any) => {
let base_url = emote.data.host.url; let base_url = emote.data.host.url;
let largest = emote.data.host.files[emote.data.host.files.length - 1]; let largest = emote.data.host.files[emote.data.host.files.length - 1];
emotes[emote.data.name] = `https:${base_url}/${largest.name}`; emotes["7tv"][emote.data.name] = `https:${base_url}/${largest.name}`;
}); });
// set 7tv key to channelEmotes // bttv
setChannelEmotes((prev) => ({ ...prev, "7tv": emotes })); data["bttv"].channel.forEach((emote: any) => {
}); emotes["bttv"][
fetch("/api/bttv/emotes?c=56418014") emote.code
.then((res) => res.json()) ] = `https://cdn.betterttv.net/emote/${emote.id}/3x`;
.then((data) => {
if (data.error) {
setErrorCode(data.error.code);
return;
}
let emotes: { [key: string]: string } = {};
data.channel.forEach((emote: any) => {
emotes[emote.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`;
}); });
data.global.forEach((emote: any) => { data["bttv"].global.forEach((emote: any) => {
emotes[emote.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`; emotes["bttv"][
emote.code
] = `https://cdn.betterttv.net/emote/${emote.id}/3x`;
}); });
// add as bttv key to channelEmotes // ffz
setChannelEmotes((prev) => ({ ...prev, bttv: emotes })); data["ffz"].channel.forEach((emote: any) => {
});
fetch("/api/ffz/emotes?s=341402")
.then((res) => res.json())
.then((data) => {
if (data.error) {
setErrorCode(data.error.code);
return;
}
let emotes: { [key: string]: string } = {};
data.channel.forEach((emote: any) => {
// ffz emotes don't have all sizes available, so we need to get the largest one by taking the largest key in the urls object // ffz emotes don't have all sizes available, so we need to get the largest one by taking the largest key in the urls object
emotes[emote.name] = `https:${ emotes["ffz"][emote.name] = `https:${
emote.urls[ emote.urls[
Math.max(...Object.keys(emote.urls).map((k) => parseInt(k))) Math.max(...Object.keys(emote.urls).map((k) => parseInt(k)))
] ]
}`; }`;
}); });
data.global.forEach((emote: any) => { data["ffz"].global.forEach((emote: any) => {
emotes[emote.name] = `https:${ emotes["ffz"][emote.name] = `https:${
emote.urls[ emote.urls[
Math.max(...Object.keys(emote.urls).map((k) => parseInt(k))) Math.max(...Object.keys(emote.urls).map((k) => parseInt(k)))
] ]
}`; }`;
}); });
// add as ffz key to channelEmotes // twitch
setChannelEmotes((prev) => ({ ...prev, ffz: emotes })); data["twitch"].channel.forEach((emote: any) => {
}); emotes["twitch"][emote.name] = emote.images["url_4x"];
fetch("/api/twitch/emotes?c=56418014")
.then((res) => res.json())
.then((data) => {
if (data.error) {
setErrorCode(data.error.code);
return;
}
let emotes: { [key: string]: string } = {};
data.channel.forEach((emote: any) => {
emotes[emote.name] = emote.images["url_4x"];
}); });
data.global.forEach((emote: any) => { data["twitch"].global.forEach((emote: any) => {
emotes[emote.name] = emote.images["url_4x"]; emotes["twitch"][emote.name] = emote.images["url_4x"];
}); });
// add as twitch key to channelEmotes // set emotes to channelEmotes
setChannelEmotes((prev) => ({ ...prev, ttv: emotes })); setChannelEmotes(emotes);
}); });
// fetch user data
fetch(`/api/fakeUsers?u=${username}`) fetch(`/api/fakeUsers?u=${username}`)
.then((res) => res.json()) .then((res) => res.json())
.then((data) => { .then((data) => {
@ -118,10 +100,8 @@ function UserPage() {
if (errorCode !== null) { if (errorCode !== null) {
// 20000 = user not found // 20000 = user not found
// 10000 = 7tv api error // 10000 = emote api error
// 10100 = Twitch api error // 10100 = twitch api error
// 10200 = BTTV api error
// 10300 = FFZ api error
const errorMsg = errorCode === 20000 ? "User not found" : "API error"; const errorMsg = errorCode === 20000 ? "User not found" : "API error";
return ( return (
<m.div <m.div
@ -331,7 +311,7 @@ function UserPage() {
</div> </div>
<div className="flex w-full flex-row items-center justify-center"> <div className="flex w-full flex-row items-center justify-center">
{ {
// show provider logo (7tv, bttv, ffz, ttv) // show provider logo (7tv, bttv, ffz, twitch)
asset.provider === "7tv" ? ( asset.provider === "7tv" ? (
<div className="mr-1 pt-[1px] text-7tv "> <div className="mr-1 pt-[1px] text-7tv ">
<SevenTVLogo /> <SevenTVLogo />
@ -345,7 +325,7 @@ function UserPage() {
<FFZLogo /> <FFZLogo />
</div> </div>
) : ( ) : (
<div className="mr-1 w-4 pt-[1px] text-ttv"> <div className="mr-1 w-4 pt-[1px] text-twitch">
<TwitchLogo /> <TwitchLogo />
</div> </div>
) )

View file

@ -16,7 +16,7 @@ module.exports = {
colors: { colors: {
"7tv": "#4fc2bc", "7tv": "#4fc2bc",
bttv: "#d50014", bttv: "#d50014",
ttv: "#9146FF", twitch: "#9146FF",
}, },
}, },
}, },