aikawa

Slackのリアクション通知からリスト表示

前回Slackのイベントで取得した、リアクションのログから一覧表示をしてみます。




Slack APIでAppに新たにReactionListを追加します(前回のReactionに追加しても良いんですが、色々追加すると権限がごちゃごちゃして来るので、お好みで)。

Add features and functionalityを選択し、Permissionsをクリックします。

ScopesのUser Token Scopesに、channels.read groups.read im.read mpim.read users.read を追加します。

上にあるOAuth Tokens & Redirect URLsの、Install App to Workspaceをクリックします。

権限のリクエストに、許可するをクリックします。

OAuth Access Tokenが表示されます。

APIにアクセスし、ユーザとチャンネル一覧をパースするためのクラスを前回のPHPと同じフォルダに用意します。OAuth Access TokenのCopyでクリップボードに値がコピーされるので、SLACK_KEY定数にペーストします。

<?php
define("SLACK_KEY", "xoxp-..."); // OAuth Token

class SlackBase{
public $Users = array();
public $UserNames = array();
public $Channels = array();
private $ChannelNames = array();

/* Cache */
// キャッシュ有無
function hasCache($url){
$path = $this->cachePath($url);
if(is_file($path)){$_SESSION["cache"][$url] = file_get_contents($path);}
return isset($_SESSION["cache"][$url]);
}
// cache取得
function getCache($url){
$path = $this->cachePath($url);
if(is_file($path) && !isset($_SESSION["cache"][$url])){
$_SESSION["cache"][$url] = file_get_contents($path);
}
return json_decode($_SESSION["cache"][$url], true);
}
// cache保存
function setCache($url, $str){
$path = $this->cachePath($url);
file_put_contents($path, $str);
$_SESSION["cache"][$url] = $str;
}
// cacheをファイル保存するpath
function cachePath($url){
$path0 = parse_url($url, PHP_URL_PATH);
// query が有れば追加
$path1 = parse_url($url, PHP_URL_QUERY);
parse_str($path1, $Arr);
unset($Arr["token"]);
if(strpos($path0, ".history") && $Arr){
ksort($Arr);
$path0 .= ".".str_replace(["&", "="], [".", "_"], http_build_query($Arr));
}
$path0 = str_replace("/", "_", $path0);
$path = CACHE_DIR."/".urlencode($path0);
return $path;
}

/* Get */
// Get Query
function buildQuery($Params=array()){
$Get = ["token"=>SLACK_KEY] + $Params;
return http_build_query($Get);
}
function get($url, $Params=array(), $cache=false){
$url = $url."?".$this->buildQuery($Params);
// cache
if($cache && $this->hasCache($url)){return $this->getCache($url);}
// get
$str = file_get_contents($url);
$Data = json_decode($str, true);
if(!colVal($Data, "ok")){
if($Data["error"] == "method_not_supported_for_channel_type"){
// Private channelへのアクセス等
}else{
var_dump($Data);
throw new Exception("データ取得に失敗");
}
}
// set cache
if($cache){$this->setCache($url, $str);}
//
return $Data;
}
// list channels
function getChannels($cache=true){
$Params = ["types"=>"public_channel,private_channel,mpim,im"];
// https://api.slack.com/changelog/2020-01-deprecating-antecedents-to-the-conversations-api
//$this->Channels = $this->get("https://slack.com/api/users.conversations", $Params, $cache); // 参加のみ
$this->Channels = $this->get("https://slack.com/api/conversations.list", $Params, $cache); // 全チャンネル
// channel names
foreach($this->Channels["channels"] as $Arr){
if(colVal($Arr, "is_im")){
$name = "@".colVal($this->UserNames, $Arr["user"]);
}else if(colVal($Arr, "is_group")){
$name = $Arr["purpose"]["value"];
}else{
$name = "#".$Arr["name"];
}
$this->ChannelNames[$Arr["id"]] = $name;
}
asort($this->ChannelNames);
return $this->ChannelNames;
}
// list users
function getUsers($cache=true){
$Arrs = $this->get("https://slack.com/api/users.list", [], $cache);
//
$this->Users = array();
$this->UserNames = array();
foreach($Arrs["members"] as $User){
$this->Users[$User["id"]] = $User;
$name = $User["name"];
if(colVal($User, "is_restricted")){ // guest
$name = $name." (Guest)";
}
if(colVal($User, "is_bot")){ // bot
$name = $name." (Bot)";
}
if(colVal($User, "deleted")){ // deleted
$name = $name." (Deleted)";
}
$this->UserNames[$User["id"]] = $name;
}
return $this->UserNames;
}
}



最後に表示用のPHP reaction_list.phpを同じフォルダに追加します。




<?php
{ // setting
define("TEMP_DIR", __DIR__."/.file");
if(!is_dir(TEMP_DIR)){mkdir(TEMP_DIR);}
define("CACHE_DIR", TEMP_DIR."/cache");
if(!is_dir(CACHE_DIR)){mkdir(CACHE_DIR);}
define("LOG_DIR", __DIR__."/logs");
// method
function colVal($Arr, $key){
return (isset($Arr[$key]))? $Arr[$key]: "";
}
include(__DIR__."/class_slack_base.php");
}
{
$slack = new SlackBase();
$Users = $slack->getUsers();
$Channels = $slack->getChannels();
}

if($handle = opendir(LOG_DIR)){
while(false !== ($file = readdir($handle))){
$path = LOG_DIR."/".$file;
if(is_file($path)){
$str = file_get_contents($path);
$json = json_decode($str, true);
if($json){
$event = $json["event"];
$channel_id = $event["item"]["channel"];
$user_id = $event["user"];
$m_user_id = $event["item_user"];
$ts = $event["event_ts"];
$reaction = $event["reaction"];
//
$m_user = colVal($Users, $m_user_id);
$user = colVal($Users, $user_id);
$channel = colVal($Channels, $channel_id);
if(!$channel){
print_r($json);
}
$time = date("Y-m-d H:i:s", $ts);
//
$line = $time."\t".$channel."で".$user."が".$m_user."の発言に:".$reaction.": のリアクションをしました。";
echo $line."\n";
}
}
}
}




reaction_list.phpを実行して、一覧表示されれば成功です。




※以前のAPIはchannels.listやim.listが使えたんですが、2020年6月10日以降に作成したAppは、deprecatedエラーが表示されるので、conversations.listを使用する必要が有ります。
以前のAppも2021年2月24日までに設定し直さないと、使えなくなる模様なので、面倒臭いですが・・・。

https://api.slack.com/changelog/2020-01-deprecating-antecedents-to-the-conversations-api