From 16396678967b65f2a3d3277058ce88013b6205a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Mon, 24 Mar 2025 14:27:07 +0100 Subject: [PATCH 1/2] Add SEO checker to tasks workflow --- .vscode/tasks.json | 19 ++++++++++++++- package-lock.json | 10 ++++---- package.json | 1 + scripts/seo-check/.gitignore | 2 ++ scripts/seo-check/seo-check.js | 43 ++++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) create mode 100644 scripts/seo-check/.gitignore create mode 100644 scripts/seo-check/seo-check.js diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3fbf407d02..efe38a0aa1 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -172,6 +172,23 @@ "panel": "shared" }, "problemMatcher": [] - } + }, + { + "label": "SEO Check (current article)", + "type": "shell", + "command": "node scripts/seo-check/seo-check.js \"${file}\"", + "options": { + "cwd": "${workspaceFolder}" + }, + "windows": { + "command": "node .\\scripts\\seo-check\\seo-check.js \"${file}\"" + }, + "group": "none", + "presentation": { + "reveal": "always", + "panel": "shared" + }, + "problemMatcher": [] + } ] } diff --git a/package-lock.json b/package-lock.json index e94490ef9e..7e3acaa75f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "license": "ISC", "dependencies": { "@arduino/docs-arduino-cc": "^2.0.29", + "dotenv": "^16.4.7", "gatsby": "^5.11.0", "gatsby-background-image": "^1.6.0", "gatsby-image": "^3.11.0", @@ -10287,14 +10288,15 @@ } }, "node_modules/dotenv": { - "version": "16.3.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.3.1.tgz", - "integrity": "sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==", + "version": "16.4.7", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", + "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", + "license": "BSD-2-Clause", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/dotenv-expand": { diff --git a/package.json b/package.json index a82c1aac57..d16a577064 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "homepage": "https://github.com/arduino/docs-content#readme", "dependencies": { "@arduino/docs-arduino-cc": "^2.0.29", + "dotenv": "^16.4.7", "gatsby": "^5.11.0", "gatsby-background-image": "^1.6.0", "gatsby-image": "^3.11.0", diff --git a/scripts/seo-check/.gitignore b/scripts/seo-check/.gitignore new file mode 100644 index 0000000000..97aca2ea1c --- /dev/null +++ b/scripts/seo-check/.gitignore @@ -0,0 +1,2 @@ +.env +node_modules \ No newline at end of file diff --git a/scripts/seo-check/seo-check.js b/scripts/seo-check/seo-check.js new file mode 100644 index 0000000000..99f40a415f --- /dev/null +++ b/scripts/seo-check/seo-check.js @@ -0,0 +1,43 @@ +require('dotenv').config({ path: __dirname + '/.env' }); +const fs = require('fs'); +const path = require('path'); +const OpenAI = require('openai'); + +// 1. Get file path from arguments +const filePath = process.argv[2]; +if (!filePath) { + console.error('❌ No file path provided.'); + process.exit(1); +} + +// 2. Read file content +const content = fs.readFileSync(filePath, 'utf8'); + +// 3. Set up OpenAI client (v4 style) +const openai = new OpenAI({ + apiKey: process.env.OPENAI_API_KEY, +}); + +// 4. Send to OpenAI +(async () => { + try { + const chatCompletion = await openai.chat.completions.create({ + model: 'gpt-4', + messages: [ + { role: 'system', content: 'You are a helpful SEO and content writing assistant.' }, + { role: 'user', content: `Please review and improve this Markdown article for SEO:\n\n${content}` } + ], + }); + + const result = chatCompletion.choices[0].message.content; + console.log('\n💬 Response from OpenAI:\n'); + console.log(result); + + // Optional: write to file + const outputPath = filePath.replace(/\.md$/, '.openai.md'); + fs.writeFileSync(outputPath, result, 'utf8'); + console.log(`\n✅ Response saved to: ${outputPath}`); + } catch (err) { + console.error('⚠️ Error communicating with OpenAI:', err); + } +})(); \ No newline at end of file From 9b16a22bd7d4ff422000f377c33e758b63789caf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20S=C3=B6derby?= <35461661+karlsoderby@users.noreply.github.com> Date: Mon, 7 Apr 2025 10:44:59 +0200 Subject: [PATCH 2/2] Update seo-check.js --- scripts/seo-check/seo-check.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/seo-check/seo-check.js b/scripts/seo-check/seo-check.js index 99f40a415f..66a16ff3c1 100644 --- a/scripts/seo-check/seo-check.js +++ b/scripts/seo-check/seo-check.js @@ -21,17 +21,26 @@ const openai = new OpenAI({ // 4. Send to OpenAI (async () => { try { + const prompt = `Please review the following markdown content, and recommend SEO improvements. + The SEO improvements should be made in coordination with the following guidelines: + - https://developers.google.com/search/docs/fundamentals/creating-helpful-content + - https://developers.google.com/search/docs/crawling-indexing/url-structure + + Please extract non-generic focus points from the content and suggest specific improvements. + You can extract specific sections from the content, place it in markdown code block, and then below, + make a markdown codeblock containing a new suggestion for the section. + + :\n\n${content}`; + const chatCompletion = await openai.chat.completions.create({ model: 'gpt-4', messages: [ { role: 'system', content: 'You are a helpful SEO and content writing assistant.' }, - { role: 'user', content: `Please review and improve this Markdown article for SEO:\n\n${content}` } + { role: 'user', content: prompt } ], }); const result = chatCompletion.choices[0].message.content; - console.log('\n💬 Response from OpenAI:\n'); - console.log(result); // Optional: write to file const outputPath = filePath.replace(/\.md$/, '.openai.md'); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy