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