Skip to content

Commit 7e7f2cc

Browse files
authored
JS script for Algolia webhook
1 parent 0bcf17a commit 7e7f2cc

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

send-blogs-to-deploy-endpoint.js

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const matter = require("gray-matter");
4+
const { default: axios } = require("axios");
5+
require("dotenv").config();
6+
const { execSync } = require("child_process");
7+
8+
const API_ENDPOINT_PRODUCTION =
9+
process.env.BLOG_POSTS_DEPLOY_TO_ALGOLIA_ENDPOINT_PRODUCTION;
10+
const API_ENDPOINT_DEVELOP =
11+
process.env.BLOG_POSTS_DEPLOY_TO_ALGOLIA_ENDPOINT_DEVELOP;
12+
13+
function transformFileNameFormat(str) {
14+
// Split the string into parts
15+
const parts = str.split("-");
16+
17+
// Join the first three parts with a slash and then the rest with a dash
18+
const transformedString = `${parts[0]}/${parts[1]}/${parts[2]}/${parts
19+
.slice(3)
20+
.join("-")}`;
21+
22+
return transformedString;
23+
}
24+
25+
function removeHtmlTags(str) {
26+
return str.replace(/<\/?[^>]+(>|$)/g, "");
27+
}
28+
29+
// Function to extract metadata from a file using 'gray-matter'
30+
const extractMetadata = (filePath) => {
31+
const fileContent = fs.readFileSync(filePath, "utf-8");
32+
const parsed = matter(fileContent);
33+
return {
34+
title: parsed.data.title,
35+
url: `/${transformFileNameFormat(path.basename(filePath, ".md"))}`,
36+
description: removeHtmlTags(parsed.data.summary),
37+
isBlog: true,
38+
id: parsed.data.id,
39+
}; // This will contain the frontmatter (metadata) such as title, description, etc.
40+
};
41+
42+
// Function to extract metadata from the previous version of a file (from the last commit)
43+
const extractPreviousMetadata = (filePath) => {
44+
try {
45+
const previousContent = execSync(`git show HEAD^:${filePath}`, {
46+
encoding: "utf-8",
47+
});
48+
const parsed = matter(previousContent);
49+
return {
50+
title: parsed.data.title,
51+
url: `/${transformFileNameFormat(path.basename(filePath, ".md"))}`,
52+
description: removeHtmlTags(parsed.data.summary),
53+
isBlog: true,
54+
id: parsed.data.id,
55+
};
56+
} catch (error) {
57+
console.error(
58+
`Error extracting previous metadata for ${filePath}: ${error}`
59+
);
60+
return null;
61+
}
62+
};
63+
64+
async function sendBlogsToAlgolia() {
65+
// Get arguments passed from the GitHub Action (new, modified, deleted files)
66+
const newFiles = process.argv[2].split(" ");
67+
const modifiedFiles = process.argv[3].split(" ");
68+
const deletedFiles = process.argv[4].split(" ");
69+
70+
// Arrays to store the metadata from new and modified files
71+
// These will be sent to the endpoint
72+
const newFilesData = [];
73+
const modifiedFilesData = [];
74+
const deletedFilesData = [];
75+
76+
// Process new files
77+
newFiles.forEach((file) => {
78+
if (file && fs.existsSync(file)) {
79+
const metadata = extractMetadata(file);
80+
newFilesData.push({ file, ...metadata });
81+
}
82+
});
83+
84+
// Process modified files (both before and after modification)
85+
modifiedFiles.forEach((file) => {
86+
if (file && fs.existsSync(file)) {
87+
const previousMetadata = extractPreviousMetadata(file);
88+
const currentMetadata = extractMetadata(file);
89+
modifiedFilesData.push({
90+
previous: previousMetadata,
91+
current: currentMetadata,
92+
});
93+
}
94+
});
95+
96+
// Process deleted files
97+
deletedFiles.forEach((file) => {
98+
if (file && fs.existsSync(file)) {
99+
const metadata = extractMetadata(file);
100+
deletedFilesData.push({ ...metadata });
101+
}
102+
});
103+
104+
try {
105+
if (!API_ENDPOINT_PRODUCTION || !API_ENDPOINT_DEVELOP) {
106+
throw new Error(
107+
"BLOG_POSTS_DEPLOY_TO_ALGOLIA_ENDPOINT_PRODUCTION or BLOG_POSTS_DEPLOY_TO_ALGOLIA_ENDPOINT_DEVELOP environment variable not configured"
108+
);
109+
}
110+
111+
try {
112+
await axios.post(API_ENDPOINT_DEVELOP, {
113+
newDocuments: newFilesData,
114+
updatedDocuments: modifiedFilesData,
115+
deletedDocuments: deletedFilesData,
116+
});
117+
} catch (error) {
118+
throw new Error(
119+
`Error sending posts to develop endpoint ${JSON.stringify(error)}`
120+
);
121+
}
122+
123+
try {
124+
await axios.post(API_ENDPOINT_PRODUCTION, {
125+
newDocuments: newFilesData,
126+
updatedDocuments: modifiedFilesData,
127+
deletedDocuments: deletedFilesData,
128+
});
129+
} catch (error) {
130+
throw new Error(
131+
`Error sending posts to production endpoint ${JSON.stringify(error)}`
132+
);
133+
}
134+
135+
console.log("Posts successfully sent to endpoints.");
136+
} catch (error) {
137+
console.error("Error generating or sending posts:", error);
138+
}
139+
}
140+
141+
sendBlogsToAlgolia();

0 commit comments

Comments
 (0)