1
0
mirror of https://github.com/spacebarchat/server.git synced 2024-11-25 11:43:07 +01:00

gifs and query params

This commit is contained in:
Puyodead1 2023-03-24 18:57:44 -04:00
parent 0d2a2c7258
commit 0dc5b19bd8
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
9 changed files with 23435 additions and 131 deletions

10047
assets/openapi.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -202,6 +202,19 @@ function apiRoutes() {
}));
}
if (route.query) {
// map to array
const query = Object.entries(route.query).map(([k, v]) => ({
name: k,
in: "query",
required: v.required,
schema: { type: v.type },
description: v.description,
}));
obj.parameters = [...(obj.parameters || []), ...query];
}
obj.tags = [...(obj.tags || []), getTag(p)].unique();
specification.paths[path] = {

View File

@ -16,34 +16,63 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
import { TenorMediaTypes } from "@spacebar/util";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
import { route } from "@spacebar/api";
import { getGifApiKey, parseGifResult } from "./trending";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
// TODO: Custom providers
const { q, media_format, locale } = req.query;
const apiKey = getGifApiKey();
const agent = new ProxyAgent();
const response = await fetch(
`https://g.tenor.com/v1/search?q=${q}&media_format=${media_format}&locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
router.get(
"/",
route({
query: {
q: {
type: "string",
required: true,
description: "Search query",
},
media_format: {
type: "string",
description: "Media format",
values: Object.keys(TenorMediaTypes).filter((key) =>
isNaN(Number(key)),
),
},
locale: {
type: "string",
description: "Locale",
},
},
);
responses: {
200: {
body: "TenorGifsResponse",
},
},
}),
async (req: Request, res: Response) => {
// TODO: Custom providers
const { q, media_format, locale } = req.query;
const { results } = await response.json();
const apiKey = getGifApiKey();
res.json(results.map(parseGifResult)).status(200);
});
const agent = new ProxyAgent();
const response = await fetch(
`https://g.tenor.com/v1/search?q=${q}&media_format=${media_format}&locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
},
);
const { results } = await response.json();
res.json(results.map(parseGifResult)).status(200);
},
);
export default router;

View File

@ -16,34 +16,58 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
import { TenorMediaTypes } from "@spacebar/util";
import { Request, Response, Router } from "express";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
import { route } from "@spacebar/api";
import { getGifApiKey, parseGifResult } from "./trending";
const router = Router();
router.get("/", route({}), async (req: Request, res: Response) => {
// TODO: Custom providers
const { media_format, locale } = req.query;
const apiKey = getGifApiKey();
const agent = new ProxyAgent();
const response = await fetch(
`https://g.tenor.com/v1/trending?media_format=${media_format}&locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
router.get(
"/",
route({
query: {
media_format: {
type: "string",
description: "Media format",
values: Object.keys(TenorMediaTypes).filter((key) =>
isNaN(Number(key)),
),
},
locale: {
type: "string",
description: "Locale",
},
},
);
responses: {
200: {
body: "TenorGifsResponse",
},
},
}),
async (req: Request, res: Response) => {
// TODO: Custom providers
const { media_format, locale } = req.query;
const { results } = await response.json();
const apiKey = getGifApiKey();
res.json(results.map(parseGifResult)).status(200);
});
const agent = new ProxyAgent();
const response = await fetch(
`https://g.tenor.com/v1/trending?media_format=${media_format}&locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
},
);
const { results } = await response.json();
res.json(results.map(parseGifResult)).status(200);
},
);
export default router;

View File

@ -16,66 +16,21 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { Router, Response, Request } from "express";
import { route } from "@spacebar/api";
import {
Config,
TenorCategoriesResults,
TenorGif,
TenorTrendingResults,
} from "@spacebar/util";
import { Request, Response, Router } from "express";
import { HTTPError } from "lambert-server";
import fetch from "node-fetch";
import ProxyAgent from "proxy-agent";
import { route } from "@spacebar/api";
import { Config } from "@spacebar/util";
import { HTTPError } from "lambert-server";
const router = Router();
// TODO: Move somewhere else
enum TENOR_GIF_TYPES {
gif,
mediumgif,
tinygif,
nanogif,
mp4,
loopedmp4,
tinymp4,
nanomp4,
webm,
tinywebm,
nanowebm,
}
type TENOR_MEDIA = {
preview: string;
url: string;
dims: number[];
size: number;
};
type TENOR_GIF = {
created: number;
hasaudio: boolean;
id: string;
media: { [type in keyof typeof TENOR_GIF_TYPES]: TENOR_MEDIA }[];
tags: string[];
title: string;
itemurl: string;
hascaption: boolean;
url: string;
};
type TENOR_CATEGORY = {
searchterm: string;
path: string;
image: string;
name: string;
};
type TENOR_CATEGORIES_RESULTS = {
tags: TENOR_CATEGORY[];
};
type TENOR_TRENDING_RESULTS = {
next: string;
results: TENOR_GIF[];
};
export function parseGifResult(result: TENOR_GIF) {
export function parseGifResult(result: TenorGif) {
return {
id: result.id,
title: result.title,
@ -97,45 +52,63 @@ export function getGifApiKey() {
return apiKey;
}
router.get("/", route({}), async (req: Request, res: Response) => {
// TODO: Custom providers
// TODO: return gifs as mp4
// const { media_format, locale } = req.query;
const { locale } = req.query;
const apiKey = getGifApiKey();
const agent = new ProxyAgent();
const [responseSource, trendGifSource] = await Promise.all([
fetch(
`https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
router.get(
"/",
route({
query: {
locale: {
type: "string",
description: "Locale",
},
),
fetch(
`https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
},
responses: {
200: {
body: "TenorTrendingResponse",
},
),
]);
},
}),
async (req: Request, res: Response) => {
// TODO: Custom providers
// TODO: return gifs as mp4
// const { media_format, locale } = req.query;
const { locale } = req.query;
const { tags } = (await responseSource.json()) as TENOR_CATEGORIES_RESULTS;
const { results } = (await trendGifSource.json()) as TENOR_TRENDING_RESULTS;
const apiKey = getGifApiKey();
res.json({
categories: tags.map((x) => ({
name: x.searchterm,
src: x.image,
})),
gifs: [parseGifResult(results[0])],
}).status(200);
});
const agent = new ProxyAgent();
const [responseSource, trendGifSource] = await Promise.all([
fetch(
`https://g.tenor.com/v1/categories?locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
},
),
fetch(
`https://g.tenor.com/v1/trending?locale=${locale}&key=${apiKey}`,
{
agent,
method: "get",
headers: { "Content-Type": "application/json" },
},
),
]);
const { tags } =
(await responseSource.json()) as TenorCategoriesResults;
const { results } =
(await trendGifSource.json()) as TenorTrendingResults;
res.json({
categories: tags.map((x) => ({
name: x.searchterm,
src: x.image,
})),
gifs: [parseGifResult(results[0])],
}).status(200);
},
);
export default router;

View File

@ -62,6 +62,14 @@ export interface RouteOptions {
event?: EVENT | EVENT[];
summary?: string;
description?: string;
query?: {
[key: string]: {
type: string;
required?: boolean;
description?: string;
values?: string[];
};
};
// test?: {
// response?: RouteResponse;
// body?: unknown;

View File

@ -0,0 +1,72 @@
export enum TenorMediaTypes {
gif,
mediumgif,
tinygif,
nanogif,
mp4,
loopedmp4,
tinymp4,
nanomp4,
webm,
tinywebm,
nanowebm,
}
export type TenorMedia = {
preview: string;
url: string;
dims: number[];
size: number;
};
export type TenorGif = {
created: number;
hasaudio: boolean;
id: string;
media: { [type in keyof typeof TenorMediaTypes]: TenorMedia }[];
tags: string[];
title: string;
itemurl: string;
hascaption: boolean;
url: string;
};
export type TenorCategory = {
searchterm: string;
path: string;
image: string;
name: string;
};
export type TenorCategoriesResults = {
tags: TenorCategory[];
};
export type TenorTrendingResults = {
next: string;
results: TenorGif[];
locale: string;
};
export type TenorSearchResults = {
next: string;
results: TenorGif[];
};
export interface TenorGifResponse {
id: string;
title: string;
url: string;
src: string;
gif_src: string;
width: number;
height: number;
preview: string;
}
export interface TenorTrendingResponse {
categories: TenorCategoriesResults;
gifs: TenorGifResponse[];
}
export type TenorGifsResponse = TenorGifResponse[];

View File

@ -13,6 +13,7 @@ export * from "./GatewayBotResponse";
export * from "./GatewayResponse";
export * from "./GenerateRegistrationTokensResponse";
export * from "./LocationMetadataResponse";
export * from "./Tenor";
export * from "./TokenResponse";
export * from "./UserProfileResponse";
export * from "./UserRelationsResponse";