Skip to content

Commit 404e17b

Browse files
committed
Latest Release Notes Parser
Latest Release Notes Parser
1 parent c4c4206 commit 404e17b

File tree

1 file changed

+203
-0
lines changed

1 file changed

+203
-0
lines changed
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
activation_example:!release vancouver, !release latest flow, !release xanadu workspace
3+
regex:!release
4+
flags:gmi
5+
*/
6+
7+
(function(current) {
8+
var input = current.text.replace(/!release/gmi, "").trim();
9+
var slacker = new x_snc_slackerbot.Slacker();
10+
11+
// Parse input to determine version and optional topic
12+
var parts = input.toLowerCase().split(/\s+/);
13+
var version = parts[0] || 'latest';
14+
var topic = parts.slice(1).join(' ');
15+
16+
// ServiceNow release version mapping
17+
var releaseMap = {
18+
'latest': 'xanadu',
19+
'xanadu': 'xanadu',
20+
'washington': 'washington',
21+
'vancouver': 'vancouver',
22+
'utah': 'utah',
23+
'tokyo': 'tokyo',
24+
'sandiego': 'sandiego',
25+
'rome': 'rome',
26+
'quebec': 'quebec'
27+
};
28+
29+
var releaseName = releaseMap[version] || version;
30+
31+
// If no input provided, show help
32+
if (!input) {
33+
var helpMessage = '*ServiceNow Release Notes Helper* :books:\n\n' +
34+
'*Usage:*\n' +
35+
'• `!release <version>` - Get release notes for a specific version\n' +
36+
'• `!release latest` - Get latest release information\n' +
37+
'• `!release latest <topic>` - Search for a topic in latest release\n' +
38+
'• `!release <version> <topic>` - Search for a topic in specific version\n\n' +
39+
'*Supported Versions:*\n' +
40+
'`xanadu`, `washington`, `vancouver`, `utah`, `tokyo`, `sandiego`, `rome`, `quebec`\n\n' +
41+
'*Examples:*\n' +
42+
'• `!release vancouver` - Vancouver release notes\n' +
43+
'• `!release latest flow` - Search for "flow" in latest release\n' +
44+
'• `!release utah workspace` - Search for "workspace" in Utah release';
45+
46+
slacker.send_chat(current, helpMessage, false);
47+
return;
48+
}
49+
50+
// Build the base URL for ServiceNow docs
51+
var baseUrl = 'https://docs.servicenow.com';
52+
var releaseNotesUrl = baseUrl + '/bundle/' + releaseName + '-release-notes/page/release-notes.html';
53+
54+
// If topic is provided, use AI to search and summarize
55+
if (topic) {
56+
searchReleaseNotes(releaseName, topic, slacker, current);
57+
} else {
58+
// Just provide the release notes link and highlights
59+
getReleaseHighlights(releaseName, releaseNotesUrl, slacker, current);
60+
}
61+
62+
/**
63+
* Get release highlights for a specific version
64+
*/
65+
function getReleaseHighlights(release, url, slacker, current) {
66+
// Fetch the release notes page
67+
var rm = new sn_ws.RESTMessageV2();
68+
rm.setHttpMethod('GET');
69+
rm.setEndpoint(url);
70+
71+
try {
72+
var response = rm.execute();
73+
var statusCode = response.getStatusCode();
74+
75+
if (statusCode === 200) {
76+
var body = response.getBody();
77+
78+
// Use AI to extract key highlights
79+
var chatReq = new sn_ws.RESTMessageV2();
80+
chatReq.setEndpoint('https://api.openai.com/v1/chat/completions');
81+
chatReq.setHttpMethod("POST");
82+
chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key"));
83+
chatReq.setRequestHeader('Content-Type', "application/json");
84+
85+
var aiBody = {
86+
"model": "gpt-4o-mini",
87+
"messages": [
88+
{
89+
"role": "system",
90+
"content": "You are a ServiceNow expert. Extract the top 5-7 key highlights from release notes. Format using Slack markdown with *bold* for feature names and bullet points. Keep it concise and developer-focused."
91+
},
92+
{
93+
"role": "user",
94+
"content": "Extract key highlights from this HTML (focus on new features, improvements, and breaking changes):\n\n" + body.substring(0, 15000)
95+
}
96+
],
97+
"max_tokens": 500
98+
};
99+
100+
chatReq.setRequestBody(JSON.stringify(aiBody));
101+
var chatResponse = chatReq.execute();
102+
var chatBody = JSON.parse(chatResponse.getBody());
103+
var highlights = chatBody.choices[0].message.content;
104+
105+
var message = '*ServiceNow ' + release.charAt(0).toUpperCase() + release.slice(1) + ' Release Notes* :rocket:\n\n' +
106+
highlights + '\n\n' +
107+
':link: <' + url + '|View Full Release Notes>';
108+
109+
slacker.send_chat(current, message, false);
110+
} else {
111+
// Fallback to direct link
112+
var fallbackMsg = '*ServiceNow ' + release.charAt(0).toUpperCase() + release.slice(1) + ' Release Notes* :books:\n\n' +
113+
':link: <' + url + '|View Release Notes>\n\n' +
114+
'_Tip: Add a topic to search, e.g., `!release ' + release + ' flow`_';
115+
116+
slacker.send_chat(current, fallbackMsg, false);
117+
}
118+
} catch (e) {
119+
gs.error('Release Notes Parser Error: ' + e.message);
120+
var errorMsg = '*ServiceNow ' + release.charAt(0).toUpperCase() + release.slice(1) + ' Release Notes* :books:\n\n' +
121+
':link: <' + url + '|View Release Notes>\n\n' +
122+
'_Tip: Add a topic to search, e.g., `!release ' + release + ' flow`_';
123+
124+
slacker.send_chat(current, errorMsg, false);
125+
}
126+
}
127+
128+
/**
129+
* Search for a specific topic in release notes
130+
*/
131+
function searchReleaseNotes(release, topic, slacker, current) {
132+
var searchUrl = 'https://www.servicenow.com/docs/bundle/' + release + '-release-notes/page/release-notes.html';
133+
134+
// Fetch the release notes page
135+
var rm = new sn_ws.RESTMessageV2();
136+
rm.setHttpMethod('GET');
137+
rm.setEndpoint(searchUrl);
138+
139+
try {
140+
var response = rm.execute();
141+
var statusCode = response.getStatusCode();
142+
143+
if (statusCode === 200) {
144+
var body = response.getBody();
145+
146+
// Use AI to search for the topic
147+
var chatReq = new sn_ws.RESTMessageV2();
148+
chatReq.setEndpoint('https://api.openai.com/v1/chat/completions');
149+
chatReq.setHttpMethod("POST");
150+
chatReq.setRequestHeader("Authorization", "Bearer " + gs.getProperty("openai.key"));
151+
chatReq.setRequestHeader('Content-Type', "application/json");
152+
153+
var aiBody = {
154+
"model": "gpt-4o-mini",
155+
"messages": [
156+
{
157+
"role": "system",
158+
"content": "You are a ServiceNow expert. Search the release notes for information about the requested topic. Provide a concise summary with key points using Slack markdown (*bold*, bullet points). If the topic is not found, say so clearly."
159+
},
160+
{
161+
"role": "user",
162+
"content": "Search for information about '" + topic + "' in these release notes:\n\n" + body.substring(0, 15000)
163+
}
164+
],
165+
"max_tokens": 600
166+
};
167+
168+
chatReq.setRequestBody(JSON.stringify(aiBody));
169+
var chatResponse = chatReq.execute();
170+
var chatBody = JSON.parse(chatResponse.getBody());
171+
var searchResults = chatBody.choices[0].message.content;
172+
173+
var message = '*ServiceNow ' + release.charAt(0).toUpperCase() + release.slice(1) + ' - "' + topic + '"* :mag:\n\n' +
174+
searchResults + '\n\n' +
175+
':link: <' + searchUrl + '|View Full Release Notes>';
176+
177+
slacker.send_chat(current, message, false);
178+
} else {
179+
// Fallback to search link
180+
var encodedTopic = encodeURIComponent(topic);
181+
var fallbackUrl = 'https://www.servicenow.com/docs/search?q=' + encodedTopic + '&facetreset=yes&filter=bundle:' + release + '-release-notes';
182+
183+
var fallbackMsg = '*Searching for "' + topic + '" in ' + release.charAt(0).toUpperCase() + release.slice(1) + '* :mag:\n\n' +
184+
'I couldn\'t fetch the release notes directly, but here\'s a search link:\n' +
185+
':link: <' + fallbackUrl + '|Search Results for "' + topic + '">';
186+
187+
slacker.send_chat(current, fallbackMsg, false);
188+
}
189+
} catch (e) {
190+
gs.error('Release Notes Search Error: ' + e.message);
191+
192+
// Fallback to search link
193+
var encodedTopic = encodeURIComponent(topic);
194+
var fallbackUrl = 'https://www.servicenow.com/docs/search?q=' + encodedTopic + '&facetreset=yes&filter=bundle:' + release + '-release-notes';
195+
196+
var errorMsg = '*Searching for "' + topic + '" in ' + release.charAt(0).toUpperCase() + release.slice(1) + '* :mag:\n\n' +
197+
':link: <' + fallbackUrl + '|Search Results for "' + topic + '">';
198+
199+
slacker.send_chat(current, errorMsg, false);
200+
}
201+
}
202+
203+
})(current);

0 commit comments

Comments
 (0)