5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

KIT DeveloperAdvent Calendar 2017

Day 10

Slackのチームメンバーをビンゴ形式で回す

Last updated at Posted at 2017-12-11

はじめに

みなさんはチームでLTなどをする際に順番決めに迷った経験などはありますか。僕は大いに迷った経験があります。じゃんけんで決めるのも良いですが、時間がかかって大変ですよね。本記事はSlackのチームメンバーを対象とし、ビンゴ形式で順番を決めるアプリについて記述します。
記事をすべて読むのがめんどくさい方はこちらからコードを確認して見てください。

今回のゴール

slackのチームに参加しているメンバーをビンゴ形式で回すものになります。
チェックボックス形式でメンバーを選択し、追加ボタンを押すとメンバーが追加されビンゴ形式で回る感じです。

# 実装 ## 1.Slack Tokenの取得 [こちら](https://api.slack.com/custom-integrations/legacy-tokens)にアクセスしSlackのトークンを取得しましょう。
このトークンはSlackのチーム情報などを取得する際に使用します。
**※赤く塗りつぶされている箇所がトークンになります。** ![スクリーンショット 2017-12-11 18.52.54.png](https://qiita-image-store.s3.amazonaws.com/0/81341/e8064aff-d0e5-8f41-bf4b-0112773254a6.png)

2.JavaScriptファイルの作成

script.jsではSlackのチームメンバー情報の取得、チームメンバーを配列に入れランダムで取得する処理などを行います。

script.js
$ = function (x) {
  return document.getElementById(x);
}

var n = 1;
var members = new Array();
var membersUse = new Array();

function paseJson() {
  var xmlHttp;
  var token = "先ほど取得したslackToken";
  var isStop = true;

  xmlHttp = new XMLHttpRequest();
  xmlHttp.open("GET", "https://slack.com/api/users.list?token=" + token, false);
  xmlHttp.send(null);
  data = xmlHttp.responseText;
  json = JSON.parse(data);
  users = json['members'];

  for (let user of users) {
    if (user['deleted'] == false) {
      members.push((user['name']));
    }
  }
  return members
}


function initCheckbox() {
  members = paseJson();
  for (member of members) {
    var box = $('box');
    box.insertAdjacentHTML('afterbegin', `<input type="checkbox" name="user" value="${member}" class="select-user"><label>${member}</label><br>`)
  }
}

function getCheckbox() {
  var checkbox = document.getElementsByName('user')
  for (i = 0; i < checkbox.length; i++) {
    if (checkbox[i].checked == true) {
      membersUse.push(checkbox[i].value);
    }
  }
  alert('追加されました');
  return membersUse;
}


function startBingo() {
  if (membersUse.length == 0) {
    alert('メンバーを選択してください');
  } else {
    $("start").style.display = "none";
    $("stop").style.display = "inline";
    isStop = false;
    roulette();
  }
}

function stopBingo() {
  $("start").style.display = "inline";
  $("stop").style.display = "none";
  isStop = true;
}

function resetBingo() {
  location.reload();
}


function roulette() {
  var id = "";
  var rnd = Math.floor(Math.random() * membersUse.length);

  if (isStop) {
    clearTimeout(id);
    $("view").innerText = membersUse[rnd];
    if (!$("out").innerText) {
      var newli = document.createElement("li");
      var list = $("out");
      var member = n + "" + membersUse[rnd];
      list.append(newli);
      newli.append(member);
    } else {
      n++;
      var newli = document.createElement("li");
      var list = $("out");
      var member = n + "" + membersUse[rnd];
      list.append(newli);
      newli.append(member);
    }
    membersUse.splice(rnd, 1);

    if (membersUse.length == 0) {
      alert("Finish");
      $("start").disabled = true;
      $("start").style.display = "none";
      $("reset").style.display = "inline";
    }
    return false;
  }

  $("view").innerText = membersUse[rnd];
  id = setTimeout("roulette()", 10);
}

3.HTMLファイルの作成

index.htmlではボタンの配置やscript.jsから送られてきたデータの出力などを行います。

index.html
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <link href="style.css" rel="stylesheet" type="text/css"/>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=10.0, user-scalable=yes">
    <title>SlackBingo</title>
    <script type="text/javascript" src="./js/script.js"></script>
</head>
<body onload="initCheckbox()">
<header>
    <div id="nav-drawer">
        <input id="nav-input" type="checkbox" class="nav-unshown">
        <label id="nav-open" for="nav-input"><span></span></label>
        <label class="nav-unshown" id="nav-close" for="nav-input"></label>
        <div id="nav-content">
            <form id="box">
                <input type="button" id="post-member" class="btn-add" value="Add" onclick="getCheckbox()">
            </form>
        </div>
    </div>
</header>
<div id="main">
    <h1>Next...</h1>
    <div class="button">
        <form>
            <input type="button" id="start" name="start" value="Start" onclick="startBingo()">
            <input type="button" id="stop" name="stop" value="Stop" onclick="stopBingo()" style="display:none;">
            <input type="button" id="reset" name="reset" value="Reset" onclick="resetBingo()" style="display:none;">
        </form>
    </div>
    <div id="view"></div>
    <ul id="out"></ul>
</div>
</body>
</html>

4.CSSファイルの作成

style.cssでは最低限のスタイルを記述しています。

style.css
html {
    color: #ffffff;
}

header {
    padding: 0;
    margin: 0;
}

body {
    min-height: 100%;
    margin: 0;
    height: 100vh;
    width: 100vw;
    background-image: url("./images/back_img2.jpg");
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center;
}

main {
    color: #ffffff;
    height: 100vh;
    width: 100vw;
    margin: auto;
}

h1 {
    margin: 0;
    text-align: center;
    padding-top: 5%;
}

#box {
    font-size: 1.3em;
    list-style: none;
}

.select-user {
    margin: 10px;
}


/*==============center button====================*/
.button {
    text-align: center;
    margin-top: 5%;
}

#start {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: transparent;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
    text-align: center;
}

#start:hover {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: #006e54;
    opacity: 0.8;
    color: #fff;
    line-height: 50px;
}

#stop {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: transparent;
    opacity: 0.8;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
}

#stop:hover {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: #bb5535;
    opacity: 0.8;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
}

#reset {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: transparent;
    opacity: 0.8;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
}

#reset:hover {
    width: 256px;
    padding: 4px 8px;
    margin: 0 8px;
    font-size: 1.2em;
    background-color: #1ab7ea;
    opacity: 0.8;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
}

#view {
    text-align: center;
    margin-top: 5%;
    font-size: 40px;
}

/*PC display*/
@media only screen and (min-width: 768px) {
    #out {
        margin: 8%;
        text-align: center;
    }

    ul {
        list-style: none;
    }

    li {
        float: left;
        width: 200px;
        word-break: keep-all;
    }
}

/*SmartPhone display*/
@media only screen and (max-width: 768px) {
    .button {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        margin: auto;
        margin-bottom: 50px;
    }

    #out {
        list-style: none;
        margin-left: 25%;
    }

    li {
    }
}

/*header*/
header {
    padding:10px;
    background: #ffffff;
    opacity: 0.7;
}

#nav-drawer {
    color: #000000;
    position: relative;
}

/**/
.nav-unshown {
    display:none;
}

/*icon space*/
#nav-open {
    display: inline-block;
    width: 30px;
    height: 22px;
    vertical-align: middle;
}

/*menu*/
#nav-open span, #nav-open span:before, #nav-open span:after {
    position: absolute;
    height: 3px;/*線の太さ*/
    width: 25px;/*長さ*/
    border-radius: 3px;
    background: #555;
    display: block;
    content: '';
    cursor: pointer;
}
#nav-open span:before {
    bottom: -8px;
}
#nav-open span:after {
    bottom: -16px;
}

/*close action*/
#nav-close {
    display: none;/*はじめは隠しておく*/
    position: fixed;
    z-index: 99;
    top: 0;/*全体に広がるように*/
    left: 0;
    width: 100%;
    height: 100%;
    background: black;
    opacity: 0;
    transition: .3s ease-in-out;
}

/*menu contents*/
#nav-content {
    overflow: auto;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 9999;/*最前面に*/
    width: 90%;/*右側に隙間を作る*/
    max-width: 330px;/*最大幅*/
    height: 100%;
    background: #fff;/*背景色*/
    transition: .3s ease-in-out;/*滑らかに表示*/
    -webkit-transform: translateX(-105%);
    transform: translateX(-105%);/*左に隠しておく*/
}

/*チェックが入ったらもろもろ表示*/
#nav-input:checked ~ #nav-close {
    display: block;/*カバーを表示*/
    opacity: .5;
}

#nav-input:checked ~ #nav-content {
    -webkit-transform: translateX(0%);
    transform: translateX(0%);/*中身を表示*/
    box-shadow: 6px 0 25px rgba(0,0,0,.15);
}

.btn-add {
    float: right;
    width: 100px;
    padding: 2px 4px;
    margin: 10px;
    font-size: 0.8em;
    background-color: #1ab7ea;
    opacity: 0.8;
    border: 2px solid #fff;
    color: #fff;
    line-height: 50px;
}

まとめ

完成系はこのようになると思います。
1512989915.gif
チャンネルなどを選択できるようになればもっと便利になるかもしれませんねw
みなさんもSlackを用いてアプリ開発をしてみてはいかがでしょうか。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?