はじめに
私が書くとつい長くなってしまうので省略しますが、channels.historyで取得できるJSONのパターンを把握したかったので調べてみました。
ただ私は英語が苦手なので、主に実際のJSONを解析して調べました。
(以前typeだけでなくsubtypeまで存在するあたりで挫折しましたw)
この記事を読むにあたっての注意点
先ほど書いたように、この記事の内容は私が参加しているチームでの内容を中心に書いています。
不足している情報は公式を参照してください。
ちなみに
Slackでいうchannelはパブリックチャンネルのことで、groupはプライベートチャンネルのことです。
(最初groupをグループメンションのことと勘違いしてしまった。)
groupにもgroups.historyというAPIがあります。
JSONのキーはchannels.historyのと同一です。 (多分)
違いはsubtypeのchannel_*がgroup_*なくらいです。
今回パブリックチャンネルのみを解析しているためchannels.historyでとしましたが
、groups.historyを使っている人も参考になると思います。
メッセージ用JSONのキーについて
私が参加しているチーム内でいろいろな種類がありそうなチャンネルをいくつか選んで分析を行いました。
その結果19個のキーを確認できました。
全部を網羅しているかわかりませんが、それぞれ概要を書いていこうと思います。
type
ユーザーの投稿であろうとBOTの投稿であろうとファイル共有であろうとmessage。
subtype
メッセージに関するイベントが入っている。
全部で26もあるので種類ごとに分類。
ユーザーに関するイベント
| 種類 | 内容 |
|---|---|
| (キーなし) | メッセージを投稿した |
| me_message | meコマンドでメッセージを投稿した |
| message_changed | メッセージを変更した |
| message_deleted | メッセージを削除した |
| pinned_item | メッセージかファイルをピン留めした |
| unpinned_item | メッセージかファイルのピン留めを外した |
ちなみに、meコマンドでメッセージを投稿すると_イタリック_になった。
(何のためのコマンドかは不明。)
BOTに関するイベント
ここでいうBOTはIncomming WebHooks・Outgoing WebHooks・BOT(アカウント)・メッセージを投稿するプログラムなどの事を指す。
| 種類 | 内容 |
|---|---|
| bot_message | BOTがメッセージを投稿した |
| bot_add | BOTを追加した |
| bot_remove | BOTを除外した |
チャンネルに関するイベント
| 種類 | 内容 |
|---|---|
| channel_name | 名前を変更した |
| channel_topic | トピックを設定・変更した |
| channel_purpose | 目的を設定・変更した |
| channel_join | ユーザーやBOTアカウントが参加した または 招待された |
| channel_leave | ユーザーやBOTアカウントが参加をやめた または 除外された |
| channel_archive | アーカイブされた |
| channel_unarchive | アーカイブから復元された |
ファイル共有に関するイベント
| 種類 | 内容 |
|---|---|
| file_comment | ファイルにコメントした |
| file_mention | 共有済みファイルにメンションした |
| file_share | ファイルを共有した |
user
ユーザーIDが入っている。
BOTが投稿したメッセージの場合はキー自体ない。
username
| タイプ | 内容 |
|---|---|
| <@ユーザーID | ユーザーアカウント名> |
| 名前 | BOTの名前 |
| 空文字 | OutgoingWebHooksより投稿した時にusernameを指定しなかった? |
| キーなし | その他メッセージ ユーザーやIncomming WebHooksのメッセージ・チャンネル操作など |
bot_id
BOTに関するメッセージ(追加・削除・投稿)の場合はBOTのIDが入っている。
ユーザーがファイルアップロードした場合は空文字になっている。
それ以外はキーが存在しない。
text
メッセージの内容が入っている。
APIを使って投稿する場合も必須のキーではあるが、空文字でもあり。
ts
UNIX形式のタイムスタンプが入っている。
メッセージの投稿日時に関する情報はこれしかないので、必要なら人が読みやすいように変換する必要がある。
attachments
例えばURL入りのメッセージを投稿した時に追加してくれる部分の情報がJSON形式で入っている。
ちなみに、APIを使って投稿する場合はこれを使うとメッセージをリッチにできる。
(別にリッチってほどではないと思う)
reactions
誰がどんなリアクションをしたかがJSON形式で入っている。
リアクションされていない場合はキーが存在しない。
edited
誰がいつ編集したかがJSON形式で入っている。
この時、textは編集後の内容になっていて編集前の内容は取得できない。
編集されていない場合はキーが存在しない。
file upload
fileに共有したファイルの情報やコメント(アップロード時に入力していた場合)などがJSON形式ではない何かで入っているっぽい。
(JSON形式ではなかったので真面目な解析はやってないです。
公式情報見に行ったらいろいろ情報が載っていたので、気が向いたら別途記事にします。)
アップロードしたファイルの場合uploadがtrueになっている。
Google ドライブのファイルなどのネット上にアップロード済みのファイルの場合はuploadが空文字になっている。
それ以外ではfile・uploadともにキーが存在しない。
display_as_bot
BOTとして表示させるかどうかが入っている?
解析結果からはキーなしと空文字を確認。
'空文字'の場合はfileキーの存在も確認。
一部fileキーあってもこのキーがない場合あり。
公式情報にはfalseが入っている例あり。
このキーに関する説明は見つけられていない。
members
チャンネルがアーカイブされた時に参加していたメンバーが配列で入っている。
それ以外はキーが存在しない。
icons
BOTからの投稿の場合アイコンに関する情報がJSON形式で入っている。
それ以外はキーが存在しない。
topic
設定・変更したトピックの内容が入っている。
変更前のトピックの内容はない。
purpose
設定・変更した目的の内容が入っている。
変更前の目的の内容はない。
is_starred
スターをつけた場合はTRUEが入っている。
item_type
ピン留めしたメッセージのタイプ?が入っている。
CとかFとかあったけどよくわからない。
old_name
チャンネル名を変更した時の古い名前が入っている。
name
チャンネル名を変更した時の新しい名前が入っている。
inviter
ユーザーやBOTをそのチャンネルに招待・追加した人のIDが入っている。
メッセージ用JSONのキーの組み合わせについて
最後に、見つけられたキーの組み合わせをsubtypeごとに載せてみます。
解析した結果を元にしているため、解析した中に存在しなかったsubtypeについては省略します。
また、ここに載せたsubtypeについても他の組み合わせが存在する可能性もあります。
どのイベントにも存在するキー
| キー | 内容 |
|---|---|
| type | message |
| ts | タイムスタンプ |
ユーザーに関するイベント
(キーなし)
メッセージを投稿した。
| キー | 内容 | 備考 |
|---|---|---|
| user | メッセージを投稿したユーザーのID | |
| text | 投稿したメッセージの内容 | |
| attachments | メッセージに含まれるリンク先の内容(JSON) | URLが含まれる場合のみ |
| edited | {user=変更したユーザーのID, ts=変更時のタイムスタンプ} | 変更済みの場合のみ |
| reactions | [{"name":"絵文字名","users":["リアクションしたユーザーのID"],"count":リアクション数}] | リアクションされている場合のみ |
| is_starred | TRUE | スターをつけられた場合のみ |
pinned_item
pinned_item message event | Slack
メッセージかファイルをピン留めした。
| キー | 内容 |
|---|---|
| user | ピン留めしたユーザーのID |
| text | <@ユーザーID|ユーザー名> pinned a message to this channel. |
| item_type | ピン留めしたメッセージのタイプ? CとかFとかあるけどよくわからない。 |
| attachments | ピン留めしたメッセージかファイルの情報(JSON) |
BOTに関するイベント
ここでいうBOTはIncomming WebHooks・Outgoing WebHooks・BOT(アカウント)・メッセージを投稿するプログラムなどの事を指す。
bot_message
BOTがメッセージを投稿した。
パターン1:プログラムから投稿したメッセージ
| キー | 内容 |
|---|---|
| username | BOT名 |
| bot_id | BOTID 一部ない場合あり?(条件不明) |
| icons | アイコン情報(JSON) |
| text | メッセージ |
| attachments | attachments(JSON) もしくは キーなし |
パターン2:連動しているGitHubからのメッセージ
| キー | 内容 |
|---|---|
| bot_id | BOTID |
| icons | アイコン情報(JSON) |
| text | メッセージ |
| attachments | attachments(JSON) |
パターン3:Incomming WebHooksのメッセージ
| キー | 内容 |
|---|---|
| username | Incomming WebHooks名 |
| bot_id | BOTID |
| icons | アイコン情報(JSON) |
| text | メッセージ |
| attachments | attachments(JSON) もしくは キーなし |
パターン4:Outgoing WebHooksのメッセージ
| キー | 内容 |
|---|---|
| username | username もしくは 空文字 |
| bot_id | BOTID |
| icons | アイコン情報(JSON) |
| text | メッセージ |
| attachments | attachments(JSON) もしくは キーなし |
パターン5:RSSのメッセージ
| キー | 内容 |
|---|---|
| username | RSS名 |
| bot_id | BOTID |
| icons | アイコン情報(JSON) |
| text | メッセージ |
| attachments | リンク先の内容(JSON) |
bot_add
BOTを追加した。
| キー | 内容 |
|---|---|
| user | BOTを追加したユーザーのID |
| text | added an integration to this channel: <インテグレーションのURL|インテグレーション名> |
| bot_id | 追加したBOTのID |
bot_remove
BOTを除外した。
| キー | 内容 |
|---|---|
| user | BOTを除外したユーザーのID |
| text | removed an integration from this channel: <インテグレーションのURL|インテグレーション名> |
| bot_id | 除外したBOTのID |
チャンネルに関するイベント
channel_name
名前を変更した。
| キー | 内容例 |
|---|---|
| user | 名前を変更したーユーザーのID |
| text | <@ユーザーID |
| old_name | 古い名前 |
| name | 新しい名前 |
channel_topic
トピックを設定・変更した。
| キー | 内容例 |
|---|---|
| user | トピックを設定・変更したユーザーのID |
| text | "<@ユーザーID|ユーザー名> set the channel topic: 設定・変更後のトピック" |
| topic | 設定・変更後のトピック |
channel_purpose
目的を設定・変更した。
| キー | 内容例 |
|---|---|
| user | 目的を設定・変更したユーザーのID |
| text | <@ユーザーID|ユーザー名> set the channel purpose: 設定・変更後の目的 |
| purpose | 設定・変更後の目的 |
channel_join
ユーザーやBOTアカウントが参加した または 招待された。
パターン1:自分からチャンネルに参加した
| キー | 内容例 |
|---|---|
| user | 参加したユーザーのID |
| text | <@ユーザーID|ユーザー名> has joined the channel |
パターン2:チャンネルに招待された
| キー | 内容例 |
|---|---|
| user | 招待されたユーザーのID |
| text | <@ユーザーID|ユーザー名> has joined the channel |
| inviter | 招待した人のユーザーID |
パターン3:BOTアカウントを追加した
| キー | 内容例 |
|---|---|
| user | 追加したBOTアカウントのID |
| text | <@BOTアカウントのID|BOT名> has joined the channel |
| inviter | 追加した人のユーザーID |
channel_leave
ユーザーが参加をやめた。
| キー | 内容例 |
|---|---|
| user | 参加をやめたユーザーのID |
| text | <@ユーザーID|ユーザー名> has left the channel |
channel_archive
アーカイブされた。
| キー | 内容例 |
|---|---|
| user | アーカイブしたユーザーの名前 |
| members | その時点でチャンネルに参加していたユーザーのID(配列) |
| text | <@ユーザーID|ユーザー名> archived the channel (w/ 参加していた人数 member) |
ファイル共有に関するイベント
file_mention
共有済みファイルにメンションした。
| キー | 内容例 |
|---|---|
| user | メンションしたユーザーのID |
| text | <@ユーザーID|ユーザー名> mentioned a file: <ファイルのURL> |
| file | メンションしたファイルの情報(JSONではない何か) |
file_share
ファイルを共有した。
パターン1:ファイルをアップロードした
| キー | 内容例 |
|---|---|
| user | ファイルをアップロードしたユーザーのID |
| text | <@ユーザーID|ユーザー名> uploaded a file: <アップロードしたファイルに割り当てられたURL |
| file | 共有したファイルの情報など(JSON形式ではない何か) |
パターン2:ファイルをアップロードすると同時にコメントした
| キー | 内容例 |
|---|---|
| user | ファイルをアップロードしたユーザーのID |
| text | <@ユーザーID|ユーザー名> uploaded a file: <アップロードしたファイルに割り当てられたURL |
| file | 共有したファイルの情報やコメントなど(JSON形式ではない何か) |
あとがき
もともとバックアップの方法について書くつもりでしたが、書いていて内容がうまくまとめられないと思ったのでJSONの解析話だけにしました。
バックアップがJSONの解析含め、いい感じにできるようになったら改めて考えてみます。
もし書いてある内容に間違い等ありましたらコメントや編集リクエストください。
こんなパターンもあったなどの話も歓迎です。
JSONをキーごとに分解するコード
JSONの分解を行うために作ったコードを置いておきます。
*コードの書き方は適当です。
function parse() {
var sheet = SpreadsheetApp.getActiveSheet();
var data = sheet.getRange("A2:A").getValues();
//A列にJSONがあり、B列以降に分解する仕様
var parseData = sheet.getRange("B:Z").getValues();
data.forEach(function(d, index, list){
var json = JSON.parse(d[0]);
Object.keys(json).forEach(function (key) {
var c = getColNumber(parseData, key);
parseData[0][c]=key;
var value;
if (json[key] == "" || json[key] == null) {
value='""'; //キーなしとキーあるけど空文字を区別する
} else if (json[key] != void 0) {
value = json[key];
}
parseData[index+1][c]=value;
});
});
sheet.getRange("B:Z").setValues(parseData);
}
function getColNumber(parseData, key) {
var cols = parseData[0];
var c=0;
while(c<cols.length){
if(cols[c]==key || cols[c]==''){
return c;
}
c++;
}
}