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 ( / ! r e l e a s e / 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