Skip to content
This repository was archived by the owner on Dec 10, 2022. It is now read-only.

Commit 94d43ba

Browse files
committed
Use the Slack bot's configured name for the web template title
1 parent 5710667 commit 94d43ba

File tree

5 files changed

+56
-18
lines changed

5 files changed

+56
-18
lines changed

src/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ const handleGet = async( request, response ) => {
8989
// TODO: This should probably be split out into a separate function of sorts, like handlePost.
9090
case '/leaderboard':
9191
if ( helpers.isTimeBasedTokenStillValid( request.query.token, request.query.ts ) ) {
92-
response.send( await leaderboard.getForWeb() );
92+
response.send( await leaderboard.getForWeb( request ) );
9393
} else {
9494
response
9595
.status( HTTP_403 )

src/events.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ const sayThankyou = ( event ) => {
8888
*/
8989
const sendHelp = ( event ) => {
9090

91-
const botUserId = event.text.match( /<@(U[A-Z0-9]{8})>/ )[1];
91+
const botUserID = helpers.extractUserID( event.text );
9292

9393
const message = (
9494
'Sure, here\'s what I can do:\n\n' +
9595
'• `@Someone++`: Add points to a user or a thing\n' +
9696
'• `@Someone--`: Subtract points from a user or a thing\n' +
97-
'• `<@' + botUserId + '> leaderboard`: Display the leaderboard\n' +
98-
'• `<@' + botUserId + '> help`: Display this message\n\n' +
97+
'• `<@' + botUserID + '> leaderboard`: Display the leaderboard\n' +
98+
'• `<@' + botUserID + '> help`: Display this message\n\n' +
9999
'You\'ll need to invite me to a channel before I can recognise ' +
100100
'`++` and `--` commands in it.\n\n' +
101101
'If you\'re a developer, you can teach me new things! ' +

src/helpers.js

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
'use strict';
88

9+
const slack = require( './slack' );
10+
911
const fs = require( 'fs' ),
1012
crypto = require( 'crypto' ),
1113
handlebars = require( 'handlebars' );
@@ -70,6 +72,19 @@ const extractPlusMinusEventData = ( text ) => {
7072
operation: data[2].substring( 0, 1 ).replace( '—', '-' )
7173
};
7274

75+
}; // ExtractPlusMinusEventData.
76+
77+
/**
78+
* Extracts a valid Slack user ID from a string of text.
79+
*
80+
* @param {string} text The string in question.
81+
* @returns {string} The first matched Slack user ID in the string, or an empty string if a match
82+
* could not be found.
83+
* @see ::isUser
84+
*/
85+
const extractUserID = ( text ) => {
86+
const match = text.match( /U[A-Z0-9]{8}/ );
87+
return match ? match[0] : '';
7388
};
7489

7590
/**
@@ -144,6 +159,7 @@ const isTimeBasedTokenStillValid = ( token, ts ) => {
144159
*
145160
* @param {string} item The string in question.
146161
* @returns {Boolean} Whether or not the string is a Slack user ID.
162+
* @see ::extractUserID()
147163
*/
148164
const isUser = ( item ) => {
149165
return item.match( /U[A-Z0-9]{8}/ ) ? true : false;
@@ -173,10 +189,13 @@ const maybeLinkItem = ( item ) => {
173189
* standard variables referenced in the header and footer, such as
174190
* 'title'. See the contents of ./html/ for more details. Some
175191
* variables may have defaults provided, which can be overridden.
192+
* @param {object} request Optional. The Express request object that resulted in this
193+
* rendering job being run. Can be used to provide additional context
194+
* to the templates.
176195
* @returns {string} HTML ready to be rendered in the browser.
177196
* @see https://handlebarsjs.com/
178197
*/
179-
const render = ( templatePath = '', context = {}) => {
198+
const render = async( templatePath, context = {}, request = {}) => {
180199

181200
// Retrieve the header and footer HTML, if we don't already have it in memory.
182201
if ( ! templates.header ) templates.header = fs.readFileSync( 'src/html/header.html', 'utf8' );
@@ -190,9 +209,11 @@ const render = ( templatePath = '', context = {}) => {
190209

191210
/* eslint-disable camelcase */ // Handlebars templates commonly use snake_case instead.
192211
const defaults = {
193-
194-
// TODO: Get this from bot's name settings in the Slack users list.
195-
site_title: 'PlusPlus++ That Works'
212+
site_title: (
213+
request.query.botUser ?
214+
await slack.getUserName( request.query.botUser ) :
215+
'Working PlusPlus++'
216+
)
196217
};
197218
/* eslint-enable camelcase */
198219

@@ -204,6 +225,7 @@ const render = ( templatePath = '', context = {}) => {
204225
module.exports = {
205226
extractCommand,
206227
extractPlusMinusEventData,
228+
extractUserID,
207229
getTimeBasedToken,
208230
getTimestamp,
209231
isPlural,

src/leaderboard.js

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,30 @@ const slack = require( './slack' ),
1010
points = require( './points' ),
1111
helpers = require( './helpers' );
1212

13+
const querystring = require( 'querystring' );
14+
1315
/**
1416
* Gets the URL for the full leaderboard, including a token to ensure that it is only viewed by
1517
* someone who has access to this Slack team.
1618
*
17-
* @param {string} hostname The hostname this app is being served on.
19+
* @param {object} request The Express request object that resulted in this handler being run.
1820
* @returns {string} The leaderboard URL, which will be picked up in ../index.js when called.
1921
*/
20-
const getLeaderboardUrl = ( hostname ) => {
21-
const ts = helpers.getTimestamp(),
22-
token = helpers.getTimeBasedToken( ts ),
23-
url = 'https://' + hostname + '/leaderboard?token=' + token + '&ts=' + ts;
22+
const getLeaderboardUrl = ( request ) => {
23+
24+
const hostname = request.headers.host,
25+
ts = helpers.getTimestamp();
26+
27+
const params = {
28+
token: helpers.getTimeBasedToken( ts ),
29+
ts,
30+
botUser: helpers.extractUserID( request.body.event.text )
31+
};
2432

33+
const url = 'https://' + hostname + '/leaderboard?' + querystring.stringify( params );
2534
return url;
26-
};
35+
36+
}; // GetLeaderboardUrl.
2737

2838
/**
2939
* Ranks items by their scores, returning them in a human readable list complete with emoji for the
@@ -127,7 +137,7 @@ const getForSlack = async( event, request ) => {
127137

128138
const messageText = (
129139
'Here you go. ' +
130-
'Or see the <' + getLeaderboardUrl( request.headers.host ) + '|whole list>.'
140+
'Or see the <' + getLeaderboardUrl( request ) + '|whole list>.'
131141
);
132142

133143
const message = {
@@ -159,9 +169,10 @@ const getForSlack = async( event, request ) => {
159169
/**
160170
* Retrieves and returns HTML for the full leaderboard, for displaying on the web.
161171
*
172+
* @param {object} request The Express request object that resulted in this handler being run.
162173
* @returns {string} HTML for the browser.
163174
*/
164-
const getForWeb = async() => {
175+
const getForWeb = async( request ) => {
165176

166177
const scores = await points.retrieveTopScores(),
167178
users = await rankItems( scores, 'users', 'object' ),
@@ -173,7 +184,7 @@ const getForWeb = async() => {
173184
title: 'Leaderboard'
174185
};
175186

176-
return helpers.render( 'src/html/leaderboard.html', data );
187+
return helpers.render( 'src/html/leaderboard.html', data, request );
177188

178189
}; // GetForWeb.
179190

tests/leaderboard.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ describe( 'getLeaderboardUrl', () => {
1717

1818
const MILLISECONDS_TO_SECONDS = 1000;
1919

20-
const leaderboardUrl = leaderboard.getLeaderboardUrl( 'example.com' ),
20+
const request = {
21+
headers: { host: 'test.local' },
22+
body: { event: { text: '<@U00000000> test' } }
23+
};
24+
25+
const leaderboardUrl = leaderboard.getLeaderboardUrl( request ),
2126
parsedUrl = new URL( leaderboardUrl ),
2227
token = parsedUrl.searchParams.get( 'token' ),
2328
ts = parsedUrl.searchParams.get( 'ts' ),

0 commit comments

Comments
 (0)