テレワーク時代だからSlackを光で通知する

# はじめに

この記事は、[ドワンゴ Advent Calendar 2020](https://qiita.com/advent-calendar/2020/dwango) の19日目です。

こんにちは、 @i4M1k0SU (読み: みこす)です。
ドワンゴでは、ニコニコ動画のWebフロントエンド開発をしています。

前回は2018年のアドベントカレンダーに参加し、AC駆動開発を行おうと思ったのですが、時間が取れず行えませんでした。
今回は少しオーバーしてしまいましたが、なんとか形にはなりました。

# 全社テレワーク化

ドワンゴでは、某感染症への対策として、テレワークの選択が可能になりました。
私の所属している部署でも全員がテレワークを選択し、自宅で業務を行っています。
2月中旬ごろからテレワークが始まり、10ヶ月ほどが経過しました。

## テレワークでの注意
ドワンゴでは、ご存知の方も多いと思いますが、主にSlackを使用しており、(部署によるかもしれませんが)ミーティングの時間などもSlackで通知されます。
また直接相談をしたいなどで、メンションを飛ばすことも多々あります。

さて、もしこの通知に気づかなかった場合、どうなるでしょうか？

オフィスであれば、誰かが直接声をかけて教えてくれるかもしれません。

しかし自宅の場合、基本的にはSlackでの通知が全てでありそれ以外での手段で気づく・気づいてもらうことが難しくなります。
(電話番号などを知っていればその限りではないので緊急の連絡ができないわけではないが)

作業に集中していたり、お手洗いで離席していたり、場合によっては自宅という都合上、合間に家事をしたり宅配の受け取りなど仕事以外のことに気を取られているかもしれません。

テレワークにおいて、Slackの通知はより気づかなければならない重要なものになります。

# 通知の種類を増やす
Slackの通知は基本的に、音とOSの通知表示によって行われます。
これはミュートにしていて、たまたま通知が表示されたタイミングで画面に視線が無い場合、見落としてしまうことになります。
もちろん通知一覧を見ることはできますが、私のような一般的なドワンゴ社員は業務に使うチャンネル以外にも大量のチャンネルに入っており縦横無尽に飛び交う通知を無視している人も少なくないため、一覧を見ることはあまりありません。

そこで重要な通知に限り、音と表示以外の別の手段で通知させることができると、見落としてしまうリスクを減らすことができます。

## 光での通知
PCとは独立したデバイスで光を使って通知できれば、周辺視野でも光っていることがわかり、気づきやすいはずです。
光で通知させるには、一般的にLEDを載せたマイコンボードをPCに接続して制御するといったことを考えるかと思います。

しかし、今回は電子工作やマイコン等を一切使わずに、光で通知を行う方法を実現します。

# ミラクル♡ライト (読み: ミラクルハートライト)
ミラクル♡ライトはサンリオピューロランド内にて、1500円で購入できるライトです。
![ミラクル♡ライト](https://www.puroland.jp/wp-content/uploads/2017/08/25th_36_01.jpg)
[参考リンク](https://www.puroland.jp/goods/25th/)

パレードに合わせて、色が変わったり点滅したりと連動する仕組みがあります。
*ミラクルいちごライトという製品も存在しますが、ここでは割愛します。*

## 仕組み
株式会社セガトイズのLiveStickという技術が利用されています。
簡単に説明すると、人の可聴音域外に制御用の音声信号を埋め込んでおき、その音声信号をライトに内蔵されたマイクが認識すると該当の点灯パターンで光るというものです。
パレードの際、音響設備から適切なタイミングでその音声信号を出力することで、会場にいる参加者全員のライトを連動させる演出を行うことができます。

参考動画: [ハローキティ「Miracle Heart Light」](https://youtu.be/HciNbvMQN8A)
<iframe width="560" height="315" src="https://www.youtube.com/embed/HciNbvMQN8A" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

詳しい仕組みは以下の2つのサイトで解説されているため、ここでは割愛します。

- [サンリオピューロランドのミラクル♡ライトの仕組み。制御と解析。 by titn-nanana](http://titn-nanana.hatenablog.com/entry/2017/12/15/200000)
- [Miracle Gift Paradeにおける3つのハートの色 by ohtake](https://ameblo.jp/ohtaket/entry-12338123508.html)

また、上記2つ目のサイトで解説されている @ohtake 氏は、ミラクル♡ライトを制御することができるWebページを公開しています。

- [Miracle Light Controller](https://ohtake.github.io/miracle-light-controller/)
    - https://github.com/ohtake/miracle-light-controller

今回は、 @ohtake 氏の解析成果を利用し、Node.jsを用いてSlackの通知をミラクル♡ライトで行えるようにします。
このような情報を公開してくださった @ohtake 氏に、この場を借りてお礼申し上げます。

# Slackで自分宛のメンションを取得する

SlackのAPIを利用し、Botとしてメンションを取得することにします。
現在、SlackのBot向けAPIにはいくつかの種類がありますが、今回は自分宛のメンションをリアルタイムで取得でき、また社内LANでも運用できるよう、外向けのポートを開ける必要のないRTM APIを利用しました。
アプリを作成し、OAuth時に `client` scopeを指定することで、自分自身としてRTM APIへ接続できるtokenが発行されます。
アプリの管理画面上でもscopeを追加する機能がありますが、`client` を選択することはできなかったので、OAuth経由で行う必要があります。
tokenの発行には簡単に行えるGet Slack Tokenというツールを利用しました。

[Get Slack Token by ru_shalm](https://rutan.github.io/get-slack-token/)

# Node.jsからミラクル♡ライトを光らせる

これが少し手間取った部分です。
@ohtake 氏の実装もJavaScriptですが、Webページで動作させるために作られているため、Node.jsとは発音部分が全く異なります。
Tone.jsという簡単に指定した周波数の音を再生できるライブラリが使われていますが、Web用のためNode.jsで利用することはできません。

Node.jsで音を鳴らすために、node-speakerというライブラリを使いました。

https://www.npmjs.com/package/speaker

このライブラリは、PCMデータを渡すと、スピーカーから音を出してくれるという機能しかありません。
PCMデータの生成を行うため、いくつかのライブラリを試しましたが、遅かったり思ったように動かなかったりしたため、ライブラリの利用を諦め自前での実装を行いました。
指定された周波数のサイン波を生成し、16bit整数のPCMデータとして返却します。

https://github.com/i4M1k0SU/MiracleHeartNotifier/blob/main/src/tone.ts#L32

# 成果物

https://github.com/i4M1k0SU/MiracleHeartNotifier

![20201220_000739.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151628/7125cd6f-5c1f-8804-66fb-e9bad894d1ed.gif)

現状はSlackで自分のIDを指定したメンション、及びDMの通知に対応しています。
ユーザーグループや `@channel` 、 `@here` にはまだ対応していません。

細かく条件を指定し、このチャンネルでは `@channel` でも通知する、とかこのチャンネルでは自分宛にメンションが来ても無視する。
また、条件ごとに通知時の点灯パターンを変更する、といった機能を実現したいと考えています。

# 他の用途への活用

音声信号だけでライトと連動できるということは、ミラクル♡ライト対応の映像を作って、動画投稿サイトに投稿するということもできそうです。

実際に、サンリオから販売されているBD・DVDには、ミラクル♡ライトと連動するものが存在しています。

[ミラクルギフトパレード　ブルーレイ[ブルーレイ] | グッズ | サンリオ](https://www.sanrio.co.jp/goods/17100937/)
> ※ピューロランドで参加グッズとして販売中の『ミラクルギフトパレードライト』、『ミラクルギフトストロベリーライト』がブルーレイを視聴しながら楽しめる音声仕様も収録しています。ライト連動音声では、ライブショーと同じようにライトが自動で点滅します。

調べてみたところ、YouTubeでは16000Hz以上の音はカットされるらしく、ミラクル♡ライトの制御信号に使われる、18500Hz〜19500Hzの音は消されてしまいます。
実際に、サンリオピューロランド内のパレードの映像がYouTubeに投稿されていますが、ミラクル♡ライトは反応しませんでした。
ニコニコ動画は条件にもよりますが、AAC 192kbpsで配信されます。
AAC-LC 192kbpsであれば、19600Hzくらいが上限になるので、もしかするとギリギリ消されないかもしれません。

# おわりに

どうにかAC駆動開発をすることができました。
間に合わせることを優先したため、適当な説明になってしまい申し訳ありません。(しかも間に合ってすらいない)

実は1年半ほど前にも同様のことをしています。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Slackでメンションが来たらミラクルハートライトを点滅させるプログラムを作った <a href="https://t.co/a1XXZYKIx9">pic.twitter.com/a1XXZYKIx9</a></p>&mdash; みこす aka 空集合 (@i4M1k0SU) <a href="https://twitter.com/i4M1k0SU/status/1132613001742176256?ref_src=twsrc%5Etfw">May 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

当時作ったものは概念実証のようなもので、一度通知したら落ちてしまったり、設定を変更することができなかったり、macOS Catalinaでは動かなかったりと、実用的ではありませんでした。
今回アドベントカレンダーに参加したことで、作り直してなんとか使えるところまで持っていくことができました。

皆さんもテレワーク時には通知に気づきやすいような工夫をし、快適なテレワークライフを送ってみてはいかがでしょうか。