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:
parent
0d2a2c7258
commit
0dc5b19bd8
10047
assets/openapi.json
Normal file
10047
assets/openapi.json
Normal file
File diff suppressed because it is too large
Load Diff
13137
assets/schemas.json
13137
assets/schemas.json
File diff suppressed because it is too large
Load Diff
@ -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] = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
72
src/util/schemas/responses/Tenor.ts
Normal file
72
src/util/schemas/responses/Tenor.ts
Normal 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[];
|
@ -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";
|
||||
|
Loading…
Reference in New Issue
Block a user