Slackチャンネルの粒度設計とそれを支える技術について

先日Slackからクイックデモ動画がYouTubeに上がりました

https://www.youtube.com/watch?v=u1mAHUvZ7Ns

SlackのデジタルHQの思想が見て取れる動画だと思います。
このやり方はSlackが昔から紹介している方法で、顧客別のチャンネルを作ってその中で関連するすべてのやり取りが行われるスタイルとして紹介されています。

これとは別件で、弊社リバネスではSalesforceを利用しているのですが、担当AEからSlackの使い方について聞かれたんですね。
「リバネスではどうつかっているのか？」と。
あんまり深く考えて来たわけではないのですが(たぶん）2016年に使い始めて早5年が経ち、現状の運用としてはこのやり方かなというのがあるので紹介したいと思います。

## リバネスでのチャンネル粒度はどうなっているか
弊社環境では97人のアクティブユーザー、1235のアクティブチャンネル中、1週間アクティブなチャンネルが305チャンネル程度になっています。
そんなリバネスのチャンネル粒度は、フェーズによって使い分けをしています。

全く提案初期のリードの場合は、上述の動画のようにクライアントチャンネルを立ててその中で議論が行われることがあります。
これは、そのリードがどこに引っかかるのかがわからないという状態のときにのみ使われます。
リードナーチャリングが進み、いろいろなプロジェクトの提案が進んでいくと、議論は徐々にプロジェクト別のチャンネルへと移行します。

## チャンネルの粒度は、グループ単位がほとんど
最初にできたのは事業部単位のチャンネルでした。
その中で、日々の活動の進捗を確認していくという使い方になっていきます。
徐々に事業部では単位が大きすぎる状態になっていきました。
そのときにできたのが、事業単位/プロジェクト単位 でのチャンネルです。
この中でやっているのは事業部単位と同様に、プロジェクト予算の達成に向けた一定の活動が含まれています。
プロジェクトの中に複数のクライアントが含まれ、それらを総合してプロジェクトの合計予算となるという動きになります。
なぜクライアント毎のチャンネルにしないのかというと、チャンネルへのpost流量が少なくなりすぎるからです。
ある程度の流量が一定量確保できるというのがSlack運営においては良い状態だと考えており、流量が確保できていないチャンネルは活動が停止しているか、炎上しかけているとか、いずれにしても通常状態ではないという判断をしています。

### プロジェクト単位/グループ単位のチャンネルが活発に動く理由
これはSlackだけではなく、周辺にあるアプリケーションとの連動が肝になっています。
例えば一番大きな営業単位であるマネージャーチャンネルには、全社に渡る事業計画の進捗を追いかけるようになっているのですが、これをうまくやるために実装しているのがシステム連携です

- Salesforce → Slack
- Slack → Salesforce
- Salesforce → Tableau →　Gmail → Salesforce → Slack

の3種類の連携を行っています。

以下では、連携の具体例について書いていますが、そもそもなぜ連携させるのかという点が重要な点です。
Salesforceは単体でレポートやダッシュボードと言った機能を持っています。
これを更に便利にビジュアライズして見せるのがBIとしてのTableauだったりします。
情報は、Slack以外のプラットフォーム(弊社の場合はほとんどのデータがSalesforce上に蓄積されています)に蓄積されており、それを活用するための機能も提供されているのに、なぜSlackに連携するのか。
これは、みんなで情報を見ることができるからです。
他のツールは、情報を見に行く必要があります。見た人が何かを考えて指示をだすようなフローになりがちです。
逆に言うと、うまく機能するかどうかは見る人の能力に依存するのです。
弊社では、なるべく情報をオープンにして全員の脳みその片隅にでも置いておけるような状態を作り出そうとしています。
Slackに情報を上手にpostすることでそれが可能になる。
あとは、誰かが閃けばよいのだと考えて、こんな実装をしています。

### Salesforce → Slack連携について
こちらは、昨年のAdvent Calendar に掲載されたSlackの @seratch さんのこちらの記事が参考になります。

https://qiita.com/seratch/items/ef9fb81828ba3c5d24c2

若干コードを改良していて


```python
                String value = params.get(name).toString();
                String regExp = '%(?![0-9a-fA-F]{2})';
                value = value.replaceAll(regExp, '%25');
                body += '&' + name + '=' + EncodingUtil.urlDecode(value, 'utf-8');
```

この部分を

```python
                String value = params.get(name).toString();
                String regExp = '%(?![0-9a-fA-F]{2})';
                value = value.replaceAll(regExp, '%25');
                String regExp_plus = '\\+';
                value = value.replaceAll(regExp_plus, '＋');
                String regExp_and = '\\&';
                value = value.replaceAll(regExp_and, 'and');
                String regExp_double = '\\"';
                value = value.replaceAll(regExp_double, '%22');
                String regExp_slash = '\\/';
                value = value.replaceAll(regExp_slash, '%2F');
                body += '&' + name + '=' + EncodingUtil.urlDecode(value, 'utf-8');
```

こんな感じに置換してます。
これをやらないと特殊文字系が入っていた場合にSlackに値を渡すところでエラーが出てしまうので注意。
今の所弊社ではこれでだいたい通ってるのですが、他にも対応が必要な文字があったら教えて下さい。

これらを実装することによって、Apexのスケジュール実行等によって欲しい情報をチャンネルにpostすることができます。
弊社の場合は、各種レポートや週報の提出漏れのアラート、勤怠情報の確定漏れアラート、請求書の提出漏れアラート、営業報告登録時の通知等に使ってます。

### Slack → Salesforce連携について

https://qiita.com/geeorgey/items/0766c4cafc14dd5d2c3b

これは6月に書いたこれが参考になります。
もともとはSalesforceにあった情報を、上述のやり方でSlackにPostし、それについたレスポンスをSalesforceに返すという方法です。
Slackは、情報の共有/人へのインプットには長けているのですが、これに対するアクションを蓄積するという機能がありません。
弊社では、コミュニケーションやアクションをSlackで。情報の蓄積はSalesforceで、という使い方をしているため、Slack→Salesforceの連携が実装できればそれが叶うということで編み出したやり方になっています。

### Salesforce → Tableau →　Gmail → Salesforce → Slackについて

詳細はこちら

https://docs.google.com/presentation/d/1k-RQ-18KStwJNnZAAJEs_yw9u91Rox48HpwU0T-JcaU/edit#slide=id.g1023d75d58d_0_420

![リバネスCIO_George_プレゼンアーカイブ_-_Google_スライド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22294/406746b5-873a-b5db-9025-ae98695650ec.png)

こんな事をやっています。

Tableauはビジュアルに訴える力がとても強力です。
これによって意思決定に速度が加わると言っても過言じゃありません。
ただ、これも上述したのですが、一人に依存するのはイマイチだと考えていて、チャンネルに投稿することによってより威力を増してくれます。

ステップとしては

- SalesforceのデータをTableauが吸い出してビジュアル化
- Tableauのサブスクライブ機能を使ってメールをユーザーに送信
- Gmailの転送機能を使ってTableauから送られてくるメールをSalesforceに転送
- Salesforceが受け取ったメールの中からファイルを抽出してSlackのAPIを叩く

という感じになっていて、実装面倒だなーと思われるかもしれないのですが、一度つくってしまえばあとは横展開がいくらでも効くのでとても実用的です。
実装方法はなぜかnoteに書いたのですがこちらを参照ください。

https://note.com/geeorgey/n/n1c19b83b26a1

## まとめ
長くなりましたが、弊社におけるSlackチャンネルの粒度とそれを支える技術についての紹介になりました。
もちろん使い方はそれぞれ色々な方法があると思うのですが、一つの参考になれば幸いです。
今年もあと僅か。身体に気をつけて駆け抜けましょう

## 他に投稿したSlack Advent Clendar ２０２１記事

https://qiita.com/geeorgey/items/a8dceb57f9d122e20893

https://qiita.com/geeorgey/items/fb99637d4024cbaf0d37

https://qiita.com/geeorgey/items/f1a1e125176cfca38454

## 今年は5つのSlackアプリを作りました！
よろしければインストールして使ってみて下さい！

- OYASUMI bot https://lne.st/oyasumilink
- TIPS https://lne.st/tips
- TimeLine for Slack https://lne.st/wr21
- YOKOKU for Slack https://lne.st/4cdy
- TASUKARU-TaskALL- https://lne.st/3x1u

### OYASUMI bot
Googleカレンダーのスケジュールに「休み」等の、休暇判定キーワードが入っていた場合に、自動的にSlackをスヌーズ状態に変更します。
メンションがあった場合に、メンションした相手にその日は休暇ですというレスを付けます。
スタッフの休暇を気持ちよく過ごしてもらう為のアプリです。

### TIPS
Slack用のリマインダーアプリです。
デフォルト機能のリマインダーは、一つのスケジュールに一つのメッセージの設定しか出来ません。
このアプリでは、一つのスケジュールに複数のメッセージを登録し、ランダムで指定された時間にpostします。
チャンネル特有のノウハウ等をスケジュール登録しておくことで、自然と情報が浸透する状態を作ります。


### TimeLine for Slack
全ての公開チャンネルのpostを一つのチャンネルにまとめるタイムラインチャンネルを生成するアプリです。
一部のチャンネルのみを集めたミックスチャンネルを作成すると、自分が必要なチャンネルだけのタイムラインを作り出すことが出来ます。
オプション機能として、メッセージ転送時にDeepL翻訳を挟むことが出来ます。

### YOKOKU for Slack
OYASUMI botの応用です。
例えば「営業」というキーワードが入った予定だけを抽出したいと思ったことはありませんか？
カレンダーをいちいち検索するのは手間がかかります。
このアプリを用いれば、特定のキーワードが入った予定を、特定のチャンネルに流すことが出来ます。

### TASUKARU 
Slackで色々な人からメンションをもらって混乱したことはありませんか？
何か頼まれていたはずだけど思い出せない…　そんな状態からあなたを救います。
TASUKARUはSlack専用のタスクマネージャーです。
デフォルトのスレッドやメンション画面では、処理が終わったpostをアーカイブすることが出来ませんが、TASUKARUならそれが出来ます。
今アクションが必要なものだけに集中することができる、それがTASUKARUです。