You'll need a free API key from OpenAI, and some command-line savvy in order to use this.
You can get an API key here:
https://beta.openai.com/account/api-keys
This also assumes you've already set up ./smolpub.sh (look at the smolpub manual if not).
Create a directory and put it in your path, maybe `~/.smolpost`
mkdir ~/.smolpost
Then set up a new npm project:
npm init -y
Now update your package JSON to match this:
{ "name": "smolpub", "version": "1.0.0", "description": "", "main": "blogpost.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { "body-parser": "^1.20.1", "cors": "^2.8.5", "express": "^4.18.2", "node-fetch": "^2.6.6", "openai": "^3.1.0" }, "keywords": [], "author": "", "license": "ISC" }
Go ahead and install dependencies:
npm install
Now create your `blogpost.js` executable:
touch blogpost.js chmod +x blogpost.js
Now populate it:
#!/usr/bin/env node const express = require("express"); const bodyParser = require("body-parser"); const { Configuration, OpenAIApi } = require("openai"); const cors = require("cors"); const fetch = require("node-fetch"); const fs = require("fs"); const path = require("path"); const child_process = require("child_process"); const os = require("os"); const configuration = new Configuration({ apiKey: "<YOUR API KEY>", }); const app = express(); app.use(bodyParser.json()); app.use(cors()); const openai = new OpenAIApi(configuration); app.listen(3001, () => { console.log("Server started on port 3001"); }); // Assign arguments to variables for better readability const slug = process.argv[2]; let body = process.argv[3]; // Check if 'body' is actually a path to a file if (fs.existsSync(body)) { // If it is, read the content of the file and use it as the body body = fs.readFileSync(body, "utf-8"); } app.post("/gpt3", async (req, res) => { await openai .createCompletion({ model: "text-davinci-003", prompt: `Please summarize the following into a short title: ${body}`, max_tokens: 100, temperature: 0.5, }) .then((response) => { res.json({ text: response.data.choices[0].text, }); }) .catch((err) => { console.log(err); res.json({ error: err, }); }); }); async function getSlug() { try { console.log("Incoming:", body); const res = await fetch("http://localhost:3001/gpt3", { method: "POST", body: JSON.stringify({ body }), headers: { "Content-Type": "application/json" }, }); const data = await res.json(); // Check if two arguments are provided if (process.argv.length !== 4) { console.error("Usage: blogpost.js <slug> <body>"); process.exit(1); } // Determine script directory const scriptsDir = path.join(os.homedir(), ".scripts/smolpub"); // Change to script directory process.chdir(scriptsDir); // trim any whitespace and linebreaks of 'data' try { data.text = data.text.trim(); // remove any quotes from 'data' data.text = data.text.replace(/"/g, ""); // Create a new file with the provided slug and write the body into the file fs.writeFileSync(slug, `# ${data.text}\n\n${body}\n`); // Publish the post and remove the file try { child_process.execSync(`smolpub.sh ${slug}`); fs.unlinkSync(slug); // stop the server process.exit(0); } catch (error) { console.error(`Error: ${error}`); process.exit(1); } } catch (error) { console.error("Error:", error); } } catch (error) { console.error("Error: ", error); } } getSlug();
Go ahead and use it like this:
./blogpost.js gpt-post "This is the body of my blog post."
Or pass a file:
./blogpost.js gpt-post some-file.txt