Browse Source

add a svg badge to show slack user status

close #114
Outsider 7 years ago
parent
commit
d844cef017
4 changed files with 72 additions and 4 deletions
  1. 1 3
      config.js
  2. 35 0
      lib/badge.js
  3. 1 0
      package.json
  4. 35 1
      routes/index.js

+ 1 - 3
config.js

@@ -4,9 +4,7 @@ module.exports = {
   // your slack team url (ex: socketio.slack.com)
   slackUrl: process.env.SLACK_URL || 'YOUR-TEAM.slack.com',
   // access token of slack
-  // You can generate it in https://api.slack.com/web#auth
-  // You should generate the token in admin user, not owner.
-  // If you generate the token in owner user, missing_scope error will be occurred.
+  // see https://github.com/outsideris/slack-invite-automation#issue-token
   //
   // You can test your token via curl:
   //   curl -X POST 'https://YOUR-SLACK-TEAM.slack.com/api/users.admin.invite' \

+ 35 - 0
lib/badge.js

@@ -0,0 +1,35 @@
+const pug = require('pug')
+
+const title = 'slack';
+const color = '#39AE85';
+
+function width(str) {
+  return 6 * str.length;
+}
+
+const svgTmpl =
+  `svg(xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width=wd height="20")\n` +
+  `  linearGradient(x2="0" y2="100%")#b\n` +
+  `    stop(offset="0" stop-color="#bbb" stop-opacity=".1")\n` +
+  `    stop(offset="1" stop-opacity=".1")\n` +
+  `  clipPath#a\n` +
+  `    rect(width=wd height="20" rx="3" fill="#fff")\n` +
+  `  g(clip-path="url(#a)")\n` +
+  `    path(fill="#555" d='M0 0h' + left + 'v20H0z')\n` +
+  `    path(fill="${color}" d='M'+left + ' 0h' + (wd-left) + 'v20H' + left +'z')\n` +
+  `    path(fill="url(#b)" d='M0 0h' + wd + 'v20H0z')\n` +
+  `  g(fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110")\n` +
+  `    text(x="195" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${title.length*54}") ${title}\n` +
+  `    text(x="195" y="140" transform="scale(.1)" textLength="${title.length*54}") ${title}\n` +
+  `    text(x=(wd * 5 + 195) y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength=(value.length*60)) #{value}\n` +
+  `    text(x=(wd * 5 + 195) y="140" transform="scale(.1)" textLength=(value.length*60)) #{value}\n`;
+
+module.exports = {
+  badge: function(presence, total) {
+    const fn = pug.compile(svgTmpl);
+    const value = `${presence}/${total}`;
+    const left = width(title) + 8;
+    const wd = left + width(value) + 22;
+    return fn({ value, wd, left });
+  },
+};

+ 1 - 0
package.json

@@ -14,6 +14,7 @@
     "i18n": "^0.8.3",
     "jade": "^1.11.0",
     "morgan": "^1.6.0",
+    "pug": "^2.0.0-rc.4",
     "request": "^2.62.0",
     "serve-favicon": "^2.3.0"
   }

+ 35 - 1
routes/index.js

@@ -1,7 +1,9 @@
 const express = require('express');
 const router = express.Router();
 const request = require('request');
+
 const config = require('../config');
+const { badge } = require('../lib/badge');
 
 router.get('/', function(req, res) {
   res.setLocale(config.locale);
@@ -33,7 +35,7 @@ router.post('/invite', function(req, res) {
               message: 'Success! Check “'+ req.body.email +'” for an invite from Slack.'
             });
           } else {
-            const error = body.error;
+            let error = body.error;
             if (error === 'already_invited' || error === 'already_in_team') {
               res.render('result', {
                 community: config.community,
@@ -105,4 +107,36 @@ router.post('/invite', function(req, res) {
   }
 });
 
+router.get('/badge.svg', (req, res) => {
+  request.get({
+    url: 'https://'+ config.slackUrl + '/api/users.list',
+    qs: {
+      token: config.slacktoken,
+      presence: true
+    }
+  }, function(err, httpResponse, body) {
+    try {
+      body = JSON.parse(body);
+    } catch(e) {
+      return res.status(404).send('');
+    }
+    if (!body.members) {
+      return res.status(404).send('');
+    }
+
+    const members = body.members.filter(function(m) {
+      return !m.is_bot;
+    });
+    const total = members.length;
+    const presence = members.filter(function(m) {
+      return m.presence === 'active';
+    }).length;
+
+    res.type('svg');
+    res.set('Cache-Control', 'max-age=0, no-cache');
+    res.set('Pragma', 'no-cache');
+    res.send(badge(presence, total));
+  });
+});
+
 module.exports = router;