66 lines
35 KiB
TypeScript
66 lines
35 KiB
TypeScript
|
import OpenAI from "openai";
|
||
|
import { z } from "zod";
|
||
|
|
||
|
// get meta data from url
|
||
|
export const MemeMakerParams = z.object({
|
||
|
query: z.string(),
|
||
|
});
|
||
|
|
||
|
export type MemeMakerParams = z.infer<typeof MemeMakerParams>;
|
||
|
|
||
|
const ai_token = process.env.OPENAI_API_KEY?.trim();
|
||
|
const openai = new OpenAI({
|
||
|
apiKey: ai_token,
|
||
|
});
|
||
|
|
||
|
const mememaker_swagger =
|
||
|
'{"openapi":"3.0.3","info":{"title":"Memegen.link","version":"11.0","description":"\n## Quickstart\n\nFetch the list of templates:\n\n```\n$ http GET https://api.memegen.link/templates\n\n[\n {\n "id": "aag",\n "name": "Ancient Aliens Guy",\n "lines": 2,\n "overlays": 0,\n "styles": [],\n "blank": "https://api.memegen.link/images/aag.png",\n "example": {\n "text": [\n "",\n "aliens"\n ],\n "url": "https://api.memegen.link/images/aag/_/aliens.png"\n },\n "source": "http://knowyourmeme.com/memes/ancient-aliens",\n },\n ...\n]\n```\n\nAdd text to create a meme:\n\n```\n$ http POST https://api.memegen.link/images template_id=aag "text[]=foo" "text[]=bar"\n\n{\n "url": "https://api.memegen.link/images/aag/foo/bar.png"\n}\n```\n\nView the image: <https://api.memegen.link/images/aag/foo/bar.png>\n\n## Links\n","license":{"name":"View the license","url":"https://github.com/jacebrowning/memegen/blob/main/LICENSE.txt"},"contact":{"name":"support","email":"support@maketested.com"}},"paths":{"/auth":{"post":{"operationId":"post~Clients.validate","summary":"Validate your API key","tags":["Clients"],"responses":{"401":{"content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","title":"Error"}}}}},"description":"Your API key is invalid"},"200":{"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","title":"Email"},"image_access":{"type":"boolean","title":"Image_Access"},"search_access":{"type":"boolean","title":"Search_Access"},"created":{"type":"string","format":"date-time","title":"Created"},"modified":{"type":"string","format":"date-time","title":"Modified"}}}}},"description":"Your API key is valid"}}}},"/images/preview.jpg":{"get":{"operationId":"get~Clients.preview","summary":"Display a preview of a custom meme","tags":["Clients"],"parameters":[{"name":"layout","schema":{"type":"string"},"description":"Text position: `default` or `top`","in":"query"},{"name":"template","schema":{"type":"string"},"description":"Template ID, URL, or custom background","in":"query"},{"name":"style","schema":{"type":"string"},"description":"Style name or custom overlay","in":"query"},{"name":"text[]","schema":{"type":"string"},"description":"Lines of text to render","in":"query"}],"responses":{"200":{"content":{"image/jpeg":{"schema":{"type":"string","format":"byte"}}},"description":"Successfully displayed a custom meme"}}}},"/fonts":{"get":{"operationId":"get~Fonts.index","summary":"List available fonts","tags":["Fonts"],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","title":"Filename"},"id":{"type":"string","title":"Id"},"alias":{"type":"string","title":"Alias"}}}}}},"description":"Successfully returned a list of fonts"}}}},"/images/custom":{"get":{"operationId":"get~Images.index_custom","summary":"List popular custom memes","tags":["Images"],"parameters":[{"name":"filter","schema":{"type":"string"},"description":"Part of the meme\'s text to match","in":"query"},{"name":"safe","schema":{"type":"boolean"},"description":"Exclude NSFW results","in":"query"}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","title":"Url"}}}}}},"description":"Successfully returned a list of custom memes"}}},"post":{"operationId":"post~Images.create_custom","summary":"Create a meme from any image","tags":["Images"],"responses":{"201":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","title":"Url"}}}}},"description":"Successfully created a meme from a custom image"}},"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"background":{"type":"string","title":"Background"},"style":{"type":"string","title":"Style"},"text":{"type":"array","items":{"type":"string"},"title":"Text"},"layout":{"type":"strin
|
||
|
|
||
|
const cat_swagger =
|
||
|
'{"openapi":"3.0.3","info":{"version":"1.0.0","title":"Cat as a service (CATAAS)","description":"Cat as a service (CATAAS) is a REST API to spread peace and love (or not) thanks to cats."},"servers":[{"url":"https://cataas.com"}],"tags":[{"name":"Cats","description":"Cataas API"},{"name":"API","description":"Public API"},{"name":"Security","description":"Security"},{"name":"Admin","description":"Admin API"}],"components":{"securitySchemes":{"jwt":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"AdminCat":{"required":["file","tags","validated"],"type":"object","properties":{"_id":{"type":"string"},"validated":{"type":"boolean"},"file":{"type":"string"},"mimetype":{"type":"string"},"size":{"type":"number"},"tags":{"type":"array","items":{"type":"string"},"default":[]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Cat":{"required":["file","tags"],"type":"object","properties":{"_id":{"type":"string"},"mimetype":{"type":"string"},"size":{"type":"number"},"tags":{"type":"array","items":{"type":"string"},"default":[]}}},"EditCat":{"required":["tags"],"type":"object","properties":{"tags":{"type":"array","items":{"type":"string"},"default":[]}}},"Error":{"type":"object","properties":{"message":{"type":"string"},"code":{"type":"number"}}},"SignIn":{"required":["name","password"],"type":"object","properties":{"username":{"type":"string"},"password":{"type":"string"}}},"SignUp":{"required":["name","password","mail","secret"],"type":"object","properties":{"username":{"type":"string"},"password":{"type":"string"},"email":{"type":"string"},"secret":{"type":"string"}}},"Token":{"type":"object","properties":{"token":{"type":"string"}}}}},"paths":{"/admin/cats":{"get":{"operationId":"admin:cats:browse","security":[{"jwt":[]}],"tags":["Admin"],"description":"Browse cats","parameters":[{"name":"limit","in":"query","schema":{"type":"integer"}},{"name":"skip","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"List of cats","content":{"application/json":{"schema":{"type":"array","items":{"required":["file","tags","validated"],"type":"object","properties":{"_id":{"type":"string"},"validated":{"type":"boolean"},"file":{"type":"string"},"mimetype":{"type":"string"},"size":{"type":"number"},"tags":{"type":"array","items":{"type":"string"},"default":[]},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}}}}}}}}},"/admin/cats/{id}/validate":{"put":{"operationId":"admin:cats:validate","security":[{"jwt":[]}],"tags":["Admin"],"description":"Activate cat","parameters":[{"name":"id","in":"path","schema":{"type":"string"},"required":true}],"responses":{"200":{"description":"Cat activated"},"404":{"description":"Cat not found"}}}},"/admin/cats/{id}":{"patch":{"operationId":"admin:cats:edit","security":[{"jwt":[]}],"tags":["Admin"],"description":"Activate cat","parameters":[{"name":"id","in":"path","schema":{"type":"string"},"required":true}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"string"}}}}}},"responses":{"200":{"description":"Cat updated"},"404":{"description":"Cat not found"}}},"delete":{"operationId":"admin:cats:delete","security":[{"jwt":[]}],"tags":["Admin"],"description":"Delete cat","parameters":[{"name":"id","in":"path","schema":{"type":"string"},"required":true}],"responses":{"203":{"description":"Cat deleted"},"404":{"description":"Cat not found"}}}},"/cat":{"get":{"operationId":"cat:random","tags":["Cats"],"description":"Get a random cat","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["square","medium","small","xsmall"]}},{"name":"filter","in":"query","schema":{"type":"string","enum":["mono","negate","custom"]}},{"name":"fit","in":"query","schema":{"type":"string","enum":["cover","contain","fill","inside","outside"]}},{"name":"position","in":"query","schema":{"type":"string","default":"center","enum":["top","right top","right","right bottom","bottom","left bottom","left","left top","center"]}},{"n
|
||
|
|
||
|
export async function meme_maker({ query }: MemeMakerParams) {
|
||
|
const res = await openai.chat.completions.create({
|
||
|
model: "gpt-4o-mini",
|
||
|
messages: [
|
||
|
{
|
||
|
role: "system",
|
||
|
content: `Use the below openapi schema to generate a meme's image URL or a Cat image URL and return the url alone.
|
||
|
|
||
|
MemeMaker OpenAPI Schema:
|
||
|
\`\`\`
|
||
|
${mememaker_swagger}
|
||
|
\`\`\`
|
||
|
|
||
|
Cat Image OpenAPI Schema:
|
||
|
\`\`\`
|
||
|
${cat_swagger}
|
||
|
\`\`\`
|
||
|
|
||
|
MemeMaker Useage:
|
||
|
- You can allow user to use external images using their public web url.
|
||
|
- You can allow user to use external images using their base64 encoded string.
|
||
|
|
||
|
Basic Cat Image Useage:
|
||
|
- /cat Will return a random cat
|
||
|
- /cat/:tag Will return a random cat with a :tag, You can combine multiple tags with :tag separator, Example: https://cataas.com/cat/orange,cute
|
||
|
- /cat/gif Will return a random gif cat \o/
|
||
|
- /cat/says/:text Will return a random cat saying :text
|
||
|
- /cat/:tag/says/:text Will return a random cat with a :tag and saying :text
|
||
|
|
||
|
Notes:
|
||
|
- You can use cat image urls in memes.
|
||
|
`,
|
||
|
},
|
||
|
{
|
||
|
role: "user",
|
||
|
content: query,
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
|
||
|
return {
|
||
|
response: res.choices[0].message.content,
|
||
|
};
|
||
|
}
|