user icon

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 Facebooktwitterlinkedintumblrmail

タグ:

名前
E-mail
URL
コメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)