ffz, bttv, twitch APIs init
This commit is contained in:
parent
37636cd583
commit
18137632f6
9 changed files with 972 additions and 24 deletions
58
misc/BTTVAPI.tsx
Normal file
58
misc/BTTVAPI.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import type RedisInstance from "ioredis";
|
||||
|
||||
async function applyCache(
|
||||
redis: RedisInstance,
|
||||
key: string,
|
||||
query: string,
|
||||
|
||||
cacheTime: number
|
||||
) {
|
||||
if (await redis.get(key)) {
|
||||
return JSON.parse((await redis.get(key)) as string);
|
||||
} else {
|
||||
const response = await fetchEndpoint(redis, query);
|
||||
if (response != null) {
|
||||
await redis.set(key, JSON.stringify(response), "EX", cacheTime);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchEndpoint(redis: RedisInstance, query: string) {
|
||||
if (await redis.get("BTTV.RATE_LIMIT")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
} else {
|
||||
await redis.set("BTTV.RATE_LIMIT", "1", "EX", 1);
|
||||
}
|
||||
|
||||
const requestHeaders = new Headers();
|
||||
requestHeaders.append("Content-Type", "application/json");
|
||||
requestHeaders.append("User-Agent", "toffee-web/indev");
|
||||
|
||||
const response = await fetch(query, {
|
||||
headers: requestHeaders,
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
async function getGlobalEmotes(redis: RedisInstance) {
|
||||
return await applyCache(
|
||||
redis,
|
||||
"BTTV.GLOBAL_EMOTES",
|
||||
"https://api.betterttv.net/3/cached/emotes/global",
|
||||
3600
|
||||
);
|
||||
}
|
||||
|
||||
async function getUserByID(redis: RedisInstance, channelID: string) {
|
||||
return await applyCache(
|
||||
redis,
|
||||
`BTTV.CHANNEL_EMOTES.${channelID}`,
|
||||
`https://api.betterttv.net/3/cached/users/twitch/${channelID}`,
|
||||
3600
|
||||
);
|
||||
}
|
||||
|
||||
export { getGlobalEmotes, getUserByID };
|
58
misc/FFZAPI.tsx
Normal file
58
misc/FFZAPI.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import type RedisInstance from "ioredis";
|
||||
|
||||
async function applyCache(
|
||||
redis: RedisInstance,
|
||||
key: string,
|
||||
query: string,
|
||||
|
||||
cacheTime: number
|
||||
) {
|
||||
if (await redis.get(key)) {
|
||||
return JSON.parse((await redis.get(key)) as string);
|
||||
} else {
|
||||
const response = await fetchEndpoint(redis, query);
|
||||
if (response != null) {
|
||||
await redis.set(key, JSON.stringify(response), "EX", cacheTime);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchEndpoint(redis: RedisInstance, query: string) {
|
||||
if (await redis.get("FFZ.RATE_LIMIT")) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
} else {
|
||||
await redis.set("FFZ.RATE_LIMIT", "1", "EX", 1);
|
||||
}
|
||||
|
||||
const requestHeaders = new Headers();
|
||||
requestHeaders.append("Content-Type", "application/json");
|
||||
requestHeaders.append("User-Agent", "toffee-web/indev");
|
||||
|
||||
const response = await fetch(query, {
|
||||
headers: requestHeaders,
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
return json;
|
||||
}
|
||||
|
||||
async function getGlobalEmotes(redis: RedisInstance) {
|
||||
return await applyCache(
|
||||
redis,
|
||||
"FFZ.GLOBAL_EMOTES",
|
||||
"https://api.frankerfacez.com/v1/set/global",
|
||||
3600
|
||||
);
|
||||
}
|
||||
|
||||
async function getEmoteSet(redis: RedisInstance, setID: string) {
|
||||
return await applyCache(
|
||||
redis,
|
||||
`FFZ.EMOTE_SET.${setID}`,
|
||||
`https://api.frankerfacez.com/v1/set/${setID}`,
|
||||
3600
|
||||
);
|
||||
}
|
||||
|
||||
export { getGlobalEmotes, getEmoteSet };
|
|
@ -3,7 +3,13 @@ const nextConfig = {
|
|||
reactStrictMode: true,
|
||||
swcMinify: true,
|
||||
images: {
|
||||
domains: ["cdn.discordapp.com", "static-cdn.jtvnw.net", "cdn.7tv.app"],
|
||||
domains: [
|
||||
"cdn.discordapp.com",
|
||||
"static-cdn.jtvnw.net",
|
||||
"cdn.7tv.app",
|
||||
"cdn.betterttv.net",
|
||||
"cdn.frankerfacez.com",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
|
|
30
pages/api/bttv/emotes.ts
Normal file
30
pages/api/bttv/emotes.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
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();
|
||||
|
||||
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 },
|
||||
});
|
||||
}
|
||||
}
|
|
@ -335,6 +335,470 @@ const fakePrices: { [key: string]: number } = {
|
|||
yoshiJAM: 137,
|
||||
zSpooky: 350,
|
||||
zyzzBass: 680,
|
||||
// bttv
|
||||
":tf:": 325,
|
||||
CiGrip: 697,
|
||||
DatSauce: 903,
|
||||
ForeverAlone: 663,
|
||||
GabeN: 497,
|
||||
HailHelix: 447,
|
||||
ShoopDaWhoop: 502,
|
||||
"M&Mjc": 196,
|
||||
bttvNice: 558,
|
||||
TwaT: 176,
|
||||
WatChuSay: 947,
|
||||
tehPoleCat: 611,
|
||||
TaxiBro: 527,
|
||||
BroBalt: 384,
|
||||
CandianRage: 431,
|
||||
"D:": 192,
|
||||
VisLaud: 966,
|
||||
KaRappa: 247,
|
||||
FishMoley: 276,
|
||||
Hhhehehe: 945,
|
||||
KKona: 596,
|
||||
PoleDoge: 485,
|
||||
sosGame: 473,
|
||||
CruW: 591,
|
||||
RarePepe: 866,
|
||||
haHAA: 979,
|
||||
FeelsBirthdayMan: 536,
|
||||
RonSmug: 776,
|
||||
KappaCool: 777,
|
||||
FeelsBadMan: 483,
|
||||
bUrself: 934,
|
||||
ConcernDoge: 520,
|
||||
FeelsGoodMan: 202,
|
||||
FireSpeed: 82,
|
||||
NaM: 412,
|
||||
SourPls: 231,
|
||||
FeelsSnowMan: 639,
|
||||
FeelsSnowyMan: 929,
|
||||
LuL: 603,
|
||||
SoSnowy: 647,
|
||||
SaltyCorn: 486,
|
||||
monkaS: 189,
|
||||
VapeNation: 570,
|
||||
ariW: 926,
|
||||
notsquishY: 438,
|
||||
FeelsAmazingMan: 92,
|
||||
DuckerZ: 417,
|
||||
IceCold: 21,
|
||||
SqShy: 84,
|
||||
Wowee: 533,
|
||||
WubTF: 494,
|
||||
cvR: 913,
|
||||
cvL: 337,
|
||||
cvHazmat: 599,
|
||||
cvMask: 423,
|
||||
DogChamp: 947,
|
||||
annytfBanana: 730,
|
||||
annySaur: 236,
|
||||
annytfBlink: 108,
|
||||
AnnySilly: 469,
|
||||
annyBlankies: 747,
|
||||
annyHop: 861,
|
||||
annyHopper: 941,
|
||||
annyTeaTime: 398,
|
||||
annyD: 530,
|
||||
annyDVibe: 907,
|
||||
annyDHyper: 451,
|
||||
annyDFast: 117,
|
||||
KissaVei: 158,
|
||||
Annie: 597,
|
||||
annyPls: 91,
|
||||
// ffz
|
||||
monkaW: 969,
|
||||
"5Head": 750,
|
||||
Prayge: 434,
|
||||
PauseChamp: 903,
|
||||
Pepega: 817,
|
||||
TWINGO: 256,
|
||||
PepeHands: 190,
|
||||
monkaTOS: 146,
|
||||
monkaHmm: 549,
|
||||
Dolan: 536,
|
||||
SmileW: 166,
|
||||
ABABABABA: 95,
|
||||
peepoBlanket: 798,
|
||||
pikachuS: 715,
|
||||
AYAYAHyper: 164,
|
||||
YEP: 371,
|
||||
widepeepoBlanket: 100,
|
||||
HandsUp: 684,
|
||||
peepoSad: 167,
|
||||
HyperKorone: 456,
|
||||
AYAYA: 503,
|
||||
forsenCD: 344,
|
||||
Hahaa: 291,
|
||||
LULW: 463,
|
||||
WICKED: 133,
|
||||
EZY: 494,
|
||||
OkayChamp: 950,
|
||||
PepegaPig: 217,
|
||||
POGGIES: 487,
|
||||
peepoWTF: 734,
|
||||
ConfusedCat: 508,
|
||||
PainPeko: 433,
|
||||
KKrikey: 235,
|
||||
COPIUM: 582,
|
||||
Madge: 595,
|
||||
Catge: 811,
|
||||
stopbeingMean: 522,
|
||||
NOPE: 262,
|
||||
OMEGALUL: 648,
|
||||
AYAYAY: 725,
|
||||
PogO: 548,
|
||||
Sadge: 41,
|
||||
PepegaPhone: 800,
|
||||
Widega: 543,
|
||||
ZrehplaR: 23,
|
||||
YooHoo: 617,
|
||||
ManChicken: 588,
|
||||
BeanieHipster: 480,
|
||||
CatBag: 253,
|
||||
ZreknarF: 143,
|
||||
LilZ: 952,
|
||||
ZliL: 662,
|
||||
LaterSooner: 375,
|
||||
BORT: 738,
|
||||
OBOY: 942,
|
||||
OiMinna: 354,
|
||||
AndKnuckles: 828,
|
||||
// twitch
|
||||
annytfRaid: 493,
|
||||
annytfNote: 893,
|
||||
annytfPout: 971,
|
||||
annytfAyaya: 180,
|
||||
annytfPika: 328,
|
||||
annytfPrime: 830,
|
||||
annytfLewd: 314,
|
||||
annytfRave: 615,
|
||||
annytfLurk: 898,
|
||||
annytfPog: 958,
|
||||
annytfD: 759,
|
||||
annytfCry: 399,
|
||||
annytfHeart: 472,
|
||||
annytfSad: 390,
|
||||
annytfMelt: 157,
|
||||
annytfWICKED: 94,
|
||||
annytfCheer: 780,
|
||||
annytfREEE: 272,
|
||||
annytfLUL: 122,
|
||||
annytfScuffed: 318,
|
||||
annytfAngy: 677,
|
||||
annytfHug: 826,
|
||||
annytfCool: 121,
|
||||
annytfPain: 16,
|
||||
annytfBonk: 949,
|
||||
annytfKnuckles: 182,
|
||||
annytfSigh: 220,
|
||||
annytfWoah: 582,
|
||||
annytfBite: 580,
|
||||
annytfSilly: 837,
|
||||
annytfWow: 381,
|
||||
annytfPray: 438,
|
||||
annytfPats: 410,
|
||||
annytfGasm: 822,
|
||||
annytfSit: 39,
|
||||
annytfFlower: 137,
|
||||
annytfLeave: 819,
|
||||
annytfGamba: 847,
|
||||
annytfLuv: 483,
|
||||
annytfHarucchiHug: 142,
|
||||
annytfAnnE: 324,
|
||||
annytfDinkDonk: 380,
|
||||
annytfAhriluv: 232,
|
||||
annytfW: 101,
|
||||
annytfWoke: 145,
|
||||
annytfBedge: 409,
|
||||
annytfBusiness: 142,
|
||||
annytfPeek: 98,
|
||||
annytfDonowall: 581,
|
||||
NewRecord: 836,
|
||||
Awwdible: 794,
|
||||
Lechonk: 567,
|
||||
Getcamped: 378,
|
||||
SUBprise: 580,
|
||||
FallHalp: 95,
|
||||
FallCry: 450,
|
||||
FallWinning: 261,
|
||||
MechaRobot: 984,
|
||||
ImTyping: 993,
|
||||
Shush: 506,
|
||||
MyAvatar: 41,
|
||||
PizzaTime: 330,
|
||||
LaundryBasket: 852,
|
||||
ModLove: 683,
|
||||
PotFriend: 605,
|
||||
Jebasted: 72,
|
||||
PogBones: 761,
|
||||
PoroSad: 357,
|
||||
KEKHeim: 290,
|
||||
CaitlynS: 874,
|
||||
HarleyWink: 244,
|
||||
WhySoSerious: 705,
|
||||
DarkKnight: 101,
|
||||
FamilyMan: 278,
|
||||
RyuChamp: 814,
|
||||
HungryPaimon: 920,
|
||||
TransgenderPride: 409,
|
||||
PansexualPride: 707,
|
||||
NonbinaryPride: 866,
|
||||
LesbianPride: 763,
|
||||
IntersexPride: 136,
|
||||
GenderFluidPride: 73,
|
||||
GayPride: 471,
|
||||
BisexualPride: 163,
|
||||
AsexualPride: 533,
|
||||
PogChamp: 898,
|
||||
GlitchNRG: 877,
|
||||
GlitchLit: 45,
|
||||
StinkyGlitch: 697,
|
||||
GlitchCat: 208,
|
||||
FootGoal: 542,
|
||||
FootYellow: 297,
|
||||
FootBall: 679,
|
||||
BlackLivesMatter: 637,
|
||||
ExtraLife: 394,
|
||||
VirtualHug: 452,
|
||||
"R-)": 779,
|
||||
"R)": 242,
|
||||
";-p": 911,
|
||||
";p": 168,
|
||||
";-P": 584,
|
||||
";P": 571,
|
||||
":-p": 758,
|
||||
":p": 709,
|
||||
":-P": 137,
|
||||
":P": 602,
|
||||
";-)": 349,
|
||||
";)": 745,
|
||||
":-\\": 30,
|
||||
":\\": 725,
|
||||
":-/": 403,
|
||||
":/": 187,
|
||||
"<3": 51,
|
||||
":-o": 622,
|
||||
":o": 384,
|
||||
":-O": 994,
|
||||
":O": 629,
|
||||
"8-)": 881,
|
||||
"B-)": 390,
|
||||
"B)": 489,
|
||||
"o.o": 570,
|
||||
o_o: 738,
|
||||
"o.O": 287,
|
||||
o_O: 168,
|
||||
"O.O": 452,
|
||||
O_O: 33,
|
||||
"O.o": 187,
|
||||
O_o: 513,
|
||||
":-Z": 729,
|
||||
":Z": 762,
|
||||
":-z": 658,
|
||||
":z": 526,
|
||||
":-|": 978,
|
||||
":|": 224,
|
||||
">(": 141,
|
||||
":-D": 699,
|
||||
":D": 926,
|
||||
":-(": 864,
|
||||
":-)": 141,
|
||||
BOP: 826,
|
||||
SingsNote: 46,
|
||||
SingsMic: 347,
|
||||
TwitchSings: 419,
|
||||
SoonerLater: 187,
|
||||
HolidayTree: 822,
|
||||
HolidaySanta: 340,
|
||||
HolidayPresent: 830,
|
||||
HolidayLog: 251,
|
||||
HolidayCookie: 105,
|
||||
GunRun: 899,
|
||||
PixelBob: 829,
|
||||
FBPenalty: 123,
|
||||
FBChallenge: 645,
|
||||
FBCatch: 769,
|
||||
FBBlock: 284,
|
||||
FBSpiral: 633,
|
||||
FBPass: 365,
|
||||
FBRun: 688,
|
||||
MaxLOL: 17,
|
||||
TwitchRPG: 258,
|
||||
PinkMercy: 369,
|
||||
MercyWing2: 2,
|
||||
MercyWing1: 546,
|
||||
PartyHat: 581,
|
||||
EarthDay: 649,
|
||||
TombRaid: 904,
|
||||
PopCorn: 485,
|
||||
FBtouchdown: 621,
|
||||
TPFufun: 321,
|
||||
TwitchVotes: 858,
|
||||
DarkMode: 90,
|
||||
HSWP: 729,
|
||||
HSCheers: 802,
|
||||
PowerUpL: 88,
|
||||
PowerUpR: 616,
|
||||
LUL: 958,
|
||||
EntropyWins: 639,
|
||||
TPcrunchyroll: 286,
|
||||
TwitchUnity: 349,
|
||||
Squid4: 548,
|
||||
Squid3: 113,
|
||||
Squid2: 768,
|
||||
Squid1: 649,
|
||||
CrreamAwk: 186,
|
||||
CarlSmile: 822,
|
||||
TwitchLit: 125,
|
||||
TehePelo: 124,
|
||||
TearGlove: 354,
|
||||
SabaPing: 94,
|
||||
PunOko: 145,
|
||||
KonCha: 656,
|
||||
Kappu: 597,
|
||||
InuyoFace: 434,
|
||||
BigPhish: 169,
|
||||
BegWan: 621,
|
||||
ThankEgg: 391,
|
||||
MorphinTime: 106,
|
||||
TheIlluminati: 531,
|
||||
TBAngel: 925,
|
||||
MVGame: 873,
|
||||
NinjaGrumpy: 345,
|
||||
PartyTime: 773,
|
||||
RlyTho: 830,
|
||||
UWot: 265,
|
||||
YouDontSay: 744,
|
||||
KAPOW: 757,
|
||||
ItsBoshyTime: 605,
|
||||
CoolStoryBob: 193,
|
||||
TriHard: 121,
|
||||
SuperVinlin: 500,
|
||||
FreakinStinkin: 860,
|
||||
Poooound: 411,
|
||||
CurseLit: 318,
|
||||
BatChest: 642,
|
||||
BrainSlug: 48,
|
||||
PrimeMe: 619,
|
||||
StrawBeary: 813,
|
||||
RaccAttack: 172,
|
||||
UncleNox: 583,
|
||||
WTRuck: 118,
|
||||
TooSpicy: 761,
|
||||
Jebaited: 363,
|
||||
DogFace: 911,
|
||||
BlargNaut: 148,
|
||||
TakeNRG: 27,
|
||||
GivePLZ: 581,
|
||||
imGlitch: 514,
|
||||
pastaThat: 48,
|
||||
copyThis: 426,
|
||||
UnSane: 97,
|
||||
DatSheffy: 289,
|
||||
TheTarFu: 818,
|
||||
PicoMause: 570,
|
||||
TinyFace: 31,
|
||||
DxCat: 538,
|
||||
RuleFive: 903,
|
||||
VoteNay: 113,
|
||||
VoteYea: 223,
|
||||
PJSugar: 11,
|
||||
DoritosChip: 187,
|
||||
OpieOP: 977,
|
||||
FutureMan: 893,
|
||||
ChefFrank: 481,
|
||||
StinkyCheese: 419,
|
||||
NomNom: 162,
|
||||
SmoocherZ: 863,
|
||||
cmonBruh: 93,
|
||||
KappaWealth: 776,
|
||||
MikeHogu: 497,
|
||||
VoHiYo: 646,
|
||||
KomodoHype: 295,
|
||||
SeriousSloth: 379,
|
||||
OSFrog: 807,
|
||||
OhMyDog: 124,
|
||||
KappaClaus: 209,
|
||||
KappaRoss: 298,
|
||||
MingLee: 338,
|
||||
SeemsGood: 89,
|
||||
twitchRaid: 258,
|
||||
bleedPurple: 949,
|
||||
duDudu: 442,
|
||||
riPepperonis: 192,
|
||||
NotLikeThis: 838,
|
||||
DendiFace: 534,
|
||||
CoolCat: 995,
|
||||
KappaPride: 915,
|
||||
ShadyLulu: 372,
|
||||
ArgieB8: 267,
|
||||
CorgiDerp: 511,
|
||||
PraiseIt: 557,
|
||||
TTours: 122,
|
||||
mcaT: 154,
|
||||
NotATK: 388,
|
||||
HeyGuys: 453,
|
||||
Mau5: 421,
|
||||
PRChase: 443,
|
||||
WutFace: 20,
|
||||
BuddhaBar: 622,
|
||||
PermaSmug: 769,
|
||||
panicBasket: 285,
|
||||
BabyRage: 315,
|
||||
HassaanChop: 246,
|
||||
TheThing: 890,
|
||||
EleGiggle: 284,
|
||||
RitzMitz: 671,
|
||||
YouWHY: 796,
|
||||
PipeHype: 343,
|
||||
BrokeBack: 440,
|
||||
ANELE: 156,
|
||||
PanicVis: 865,
|
||||
GrammarKing: 77,
|
||||
PeoplesChamp: 634,
|
||||
SoBayed: 700,
|
||||
BigBrother: 657,
|
||||
Keepo: 800,
|
||||
Kippa: 835,
|
||||
RalpherZ: 322,
|
||||
TF2John: 862,
|
||||
ThunBeast: 408,
|
||||
WholeWheat: 193,
|
||||
DAESuppy: 787,
|
||||
FailFish: 395,
|
||||
HotPokket: 399,
|
||||
ResidentSleeper: 460,
|
||||
FUNgineer: 747,
|
||||
PMSTwin: 830,
|
||||
ShazBotstix: 315,
|
||||
BibleThump: 278,
|
||||
AsianGlow: 461,
|
||||
DBstyle: 968,
|
||||
BloodTrail: 687,
|
||||
OneHand: 801,
|
||||
FrankerZ: 893,
|
||||
SMOrc: 727,
|
||||
ArsonNoSexy: 99,
|
||||
PunchTrees: 762,
|
||||
SSSsss: 800,
|
||||
Kreygasm: 413,
|
||||
KevinTurtle: 111,
|
||||
PJSalt: 115,
|
||||
SwiftRage: 251,
|
||||
DansGame: 46,
|
||||
GingerPower: 762,
|
||||
BCWarrior: 409,
|
||||
MrDestructoid: 811,
|
||||
JonCarnage: 359,
|
||||
Kappa: 40,
|
||||
RedCoat: 789,
|
||||
TheRinger: 669,
|
||||
StoneLightning: 867,
|
||||
OptimizePrime: 654,
|
||||
JKanStyle: 655,
|
||||
":)": 594,
|
||||
};
|
||||
|
||||
export { fakePrices };
|
||||
|
|
|
@ -175,15 +175,25 @@ const fakeData: fakeDataEntry[] = [
|
|||
{
|
||||
name: "annykiss",
|
||||
count: 8,
|
||||
provider: "ttv",
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "HUH",
|
||||
count: 1,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfSigh",
|
||||
count: 1,
|
||||
provider: "ttv",
|
||||
},
|
||||
{
|
||||
name: "GabeN",
|
||||
count: 3,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "widepeepoMASTURBATION77769420GANGSHITNOMOREFORTNITE19DOLLERFORTNITECARD",
|
||||
name: "widepeepoBlanket",
|
||||
count: 1,
|
||||
provider: "ffz",
|
||||
},
|
||||
|
@ -212,6 +222,21 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 727,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "AnnySilly",
|
||||
count: 4,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annytfHeart",
|
||||
count: 98,
|
||||
provider: "ttv",
|
||||
},
|
||||
{
|
||||
name: "Catge",
|
||||
count: 4,
|
||||
provider: "ffz",
|
||||
},
|
||||
],
|
||||
badges: [adminBadge, botDevBadge],
|
||||
},
|
||||
|
@ -232,11 +257,26 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 92,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "KissaVei",
|
||||
count: 1,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "SNIFFA",
|
||||
count: 1219,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "FeelsBirthdayMan",
|
||||
count: 1,
|
||||
provider: "ffz",
|
||||
},
|
||||
{
|
||||
name: "annytfRave",
|
||||
count: 5,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
badges: [adminBadge, botDevBadge],
|
||||
},
|
||||
|
@ -252,6 +292,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 46,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "GabeN",
|
||||
count: 3,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "ThisStream",
|
||||
count: 210,
|
||||
|
@ -262,6 +307,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 91,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfMelt",
|
||||
count: 16,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
badges: [CEOBadge, adminBadge],
|
||||
},
|
||||
|
@ -278,9 +328,9 @@ const fakeData: fakeDataEntry[] = [
|
|||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "golive",
|
||||
count: 90,
|
||||
provider: "7tv",
|
||||
name: "annyHop",
|
||||
count: 61,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annyExcitedHug",
|
||||
|
@ -292,6 +342,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 65,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "peepoWTF",
|
||||
count: 60,
|
||||
provider: "ffz",
|
||||
},
|
||||
{
|
||||
name: "annytfAngy",
|
||||
count: 90,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
badges: [adminBadge, botDevBadge],
|
||||
},
|
||||
|
@ -331,6 +391,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 10,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annySaur",
|
||||
count: 7,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "BAND",
|
||||
count: 49,
|
||||
|
@ -341,6 +406,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 78,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "PepegaPhone",
|
||||
count: 142,
|
||||
provider: "ffz",
|
||||
},
|
||||
{
|
||||
name: "annytfHug",
|
||||
count: 19,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -356,9 +431,9 @@ const fakeData: fakeDataEntry[] = [
|
|||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "peepoTalk",
|
||||
count: 73,
|
||||
provider: "7tv",
|
||||
name: "annytfLUL",
|
||||
count: 9,
|
||||
provider: "ttv",
|
||||
},
|
||||
{
|
||||
name: "peepoSnow",
|
||||
|
@ -371,9 +446,14 @@ const fakeData: fakeDataEntry[] = [
|
|||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "xdd666",
|
||||
count: 53,
|
||||
provider: "7tv",
|
||||
name: "annyBlankies",
|
||||
count: 88,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "TWINGO",
|
||||
count: 98,
|
||||
provider: "ffz",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -394,11 +474,21 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 64,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfBanana",
|
||||
count: 15,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "ewLeague",
|
||||
count: 64,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfPain",
|
||||
count: 37,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -418,6 +508,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 47,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "GabeN",
|
||||
count: 52,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "GroupWankge",
|
||||
count: 38,
|
||||
|
@ -428,6 +523,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 90,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfKnuckles",
|
||||
count: 2,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -447,11 +547,26 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 5,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyPls",
|
||||
count: 5,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "golive",
|
||||
count: 46,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "COPIUM",
|
||||
count: 82,
|
||||
provider: "ffz",
|
||||
},
|
||||
{
|
||||
name: "annytfCheer",
|
||||
count: 54,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -481,6 +596,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 13,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfBlink",
|
||||
count: 10,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annytfBonk",
|
||||
count: 77,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -500,6 +625,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 100,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyHop",
|
||||
count: 16,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "AndKnuckles",
|
||||
count: 17,
|
||||
provider: "ffz",
|
||||
},
|
||||
{
|
||||
name: "yoshiJAM",
|
||||
count: 67,
|
||||
|
@ -510,6 +645,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 59,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfSit",
|
||||
count: 53,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -529,6 +669,11 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 82,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyDFast",
|
||||
count: 22,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "PeepoKittyHug",
|
||||
count: 7,
|
||||
|
@ -553,11 +698,21 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 62,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyBlankies",
|
||||
count: 74,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "anyatf",
|
||||
count: 24,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfGamba",
|
||||
count: 32,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -577,11 +732,21 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 61,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "Annie",
|
||||
count: 24,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "Lagging",
|
||||
count: 92,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annytfFlower",
|
||||
count: 33,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -606,6 +771,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 7,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyHopper",
|
||||
count: 24,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annytfFlower",
|
||||
count: 79,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -630,6 +805,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 32,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "AngelThump",
|
||||
count: 41,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annytfSad",
|
||||
count: 2,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
@ -654,6 +839,16 @@ const fakeData: fakeDataEntry[] = [
|
|||
count: 99,
|
||||
provider: "7tv",
|
||||
},
|
||||
{
|
||||
name: "annyBlankies",
|
||||
count: 42,
|
||||
provider: "bttv",
|
||||
},
|
||||
{
|
||||
name: "annytfHeart",
|
||||
count: 63,
|
||||
provider: "ttv",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
30
pages/api/ffz/emotes.ts
Normal file
30
pages/api/ffz/emotes.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
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();
|
||||
|
||||
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 } });
|
||||
}
|
||||
}
|
30
pages/api/twitch/emotes.ts
Normal file
30
pages/api/twitch/emotes.ts
Normal file
|
@ -0,0 +1,30 @@
|
|||
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();
|
||||
|
||||
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 },
|
||||
});
|
||||
}
|
||||
}
|
|
@ -9,9 +9,9 @@ import Loading from "../../../components/common/Loading";
|
|||
// TODO: Animations
|
||||
|
||||
function UserPage() {
|
||||
const [channelEmotes, setChannelEmotes] = useState<{ [key: string]: string }>(
|
||||
{}
|
||||
);
|
||||
const [channelEmotes, setChannelEmotes] = useState<{
|
||||
[key: string]: { [key: string]: string };
|
||||
}>({});
|
||||
const [userData, setUserData] = useState<{ [key: string]: any }>({});
|
||||
const [errorCode, setErrorCode] = useState<number | null>(null);
|
||||
const router = useRouter();
|
||||
|
@ -36,7 +36,74 @@ function UserPage() {
|
|||
let largest = emote.data.host.files[emote.data.host.files.length - 1];
|
||||
emotes[emote.data.name] = `https:${base_url}/${largest.name}`;
|
||||
});
|
||||
setChannelEmotes(emotes);
|
||||
// same for global emotes
|
||||
data.global.namedEmoteSet.emotes.forEach((emote: any) => {
|
||||
let base_url = emote.data.host.url;
|
||||
let largest = emote.data.host.files[emote.data.host.files.length - 1];
|
||||
emotes[emote.data.name] = `https:${base_url}/${largest.name}`;
|
||||
});
|
||||
// set 7tv key to channelEmotes
|
||||
setChannelEmotes((prev) => ({ ...prev, "7tv": emotes }));
|
||||
});
|
||||
fetch("/api/bttv/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.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`;
|
||||
});
|
||||
data.global.forEach((emote: any) => {
|
||||
emotes[emote.code] = `https://cdn.betterttv.net/emote/${emote.id}/3x`;
|
||||
});
|
||||
// add as bttv key to channelEmotes
|
||||
setChannelEmotes((prev) => ({ ...prev, bttv: emotes }));
|
||||
});
|
||||
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
|
||||
emotes[emote.name] = `https:${
|
||||
emote.urls[
|
||||
Math.max(...Object.keys(emote.urls).map((k) => parseInt(k)))
|
||||
]
|
||||
}`;
|
||||
});
|
||||
data.global.forEach((emote: any) => {
|
||||
emotes[emote.name] = `https:${
|
||||
emote.urls[
|
||||
Math.max(...Object.keys(emote.urls).map((k) => parseInt(k)))
|
||||
]
|
||||
}`;
|
||||
});
|
||||
// add as ffz key to channelEmotes
|
||||
setChannelEmotes((prev) => ({ ...prev, ffz: emotes }));
|
||||
});
|
||||
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) => {
|
||||
emotes[emote.name] = emote.images["url_4x"];
|
||||
});
|
||||
// add as twitch key to channelEmotes
|
||||
setChannelEmotes((prev) => ({ ...prev, ttv: emotes }));
|
||||
});
|
||||
fetch(`/api/fakeUsers?u=${username}`)
|
||||
.then((res) => res.json())
|
||||
|
@ -53,6 +120,8 @@ function UserPage() {
|
|||
// 20000 = user not found
|
||||
// 10000 = 7tv api error
|
||||
// 10100 = Twitch api error
|
||||
// 10200 = BTTV api error
|
||||
// 10300 = FFZ api error
|
||||
const errorMsg = errorCode === 20000 ? "User not found" : "API error";
|
||||
return (
|
||||
<m.div
|
||||
|
@ -66,9 +135,9 @@ function UserPage() {
|
|||
);
|
||||
}
|
||||
|
||||
// if json is empty
|
||||
// if json is empty, and if channelEmotes is incomplete, show loading screen
|
||||
if (
|
||||
Object.keys(channelEmotes).length === 0 ||
|
||||
Object.keys(channelEmotes).length < 4 ||
|
||||
!userData ||
|
||||
Object.keys(userData).length === 0
|
||||
) {
|
||||
|
@ -78,7 +147,7 @@ function UserPage() {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
console.log(channelEmotes);
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
|
@ -100,6 +169,7 @@ function UserPage() {
|
|||
alt="User avatar"
|
||||
width={140}
|
||||
height={140}
|
||||
priority
|
||||
className="absolute rounded-lg border-4"
|
||||
style={{
|
||||
borderColor: userData.badges[0]
|
||||
|
@ -217,14 +287,21 @@ function UserPage() {
|
|||
>
|
||||
<div className="flex h-44 w-full max-w-[256px] flex-col items-center rounded-xl bg-zinc-900 bg-opacity-80 p-2">
|
||||
<div className="mt-2 mb-2 h-24 w-24">
|
||||
<div className="flex h-full w-full items-center justify-center p-2">
|
||||
<div className="flex h-full w-full items-center justify-start p-2">
|
||||
{
|
||||
// if error code is 10000, show placeholder image
|
||||
errorCode === 10000 ? (
|
||||
// if error code is 10000 or emote does not exist, show placeholder image
|
||||
errorCode === 10000 ||
|
||||
channelEmotes[asset.provider] === undefined ||
|
||||
channelEmotes[asset.provider][asset.name] ===
|
||||
undefined ? (
|
||||
<h1 className="text-center text-zinc-400">{`404 :(`}</h1>
|
||||
) : (
|
||||
<Image
|
||||
src={channelEmotes[asset.name]}
|
||||
src={
|
||||
channelEmotes[asset.provider][
|
||||
asset.name
|
||||
] ?? ""
|
||||
}
|
||||
alt={asset.name}
|
||||
width={100}
|
||||
height={100}
|
||||
|
@ -245,7 +322,7 @@ function UserPage() {
|
|||
</div>
|
||||
<div className="flex w-full flex-row items-center justify-center">
|
||||
{
|
||||
// show provider logo (7tv, bttv, ffz, twitch)
|
||||
// show provider logo (7tv, bttv, ffz, ttv)
|
||||
asset.provider === "7tv" ? (
|
||||
<div className="mr-1 pt-[1px] text-7tv ">
|
||||
<SevenTVLogo />
|
||||
|
|
Loading…
Reference in a new issue