web/search_tweets.php
author ymh <ymh.work@gmail.com>
Sat, 19 Oct 2024 01:42:20 +0200
changeset 1565 b1d408b2381d
parent 1558 761ba7426984
permissions -rw-r--r--
upgrade metadataplayer

<?php
use Abraham\TwitterOAuth\TwitterOAuth;
use GuzzleHttp\Client;

if (isset ($_GET['callback'])) {
	header("Content-type: text/javascript");
} else {
	header("Content-type: application/json");
}

include_once 'common.php';

function searchTwitter($token, $request_vars) {
    $connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, $token['oauth_token'], $token['oauth_token_secret']);
    $statuses = $connection->get("search/tweets", $request_vars);

    return array_map(function($tweet) { 
        $res = $tweet;
        $res['type'] = "Twitter";
        return $res;
    }, $statuses);
}

function searchMastodon($token, $request_vars, $domain) {

    $mapTootDomain = function($toot) use ($domain) {
        return mapToot($toot, $domain);
    };

    $tag = $request_vars['q'] ?? false;

    $rv = [
        'limit' => min(intval($request_vars['count'] ?? 40), 40),
    ];

    if ($request_vars['since_id'] ?? false) {
        $rv['since_id'] = $request_vars['since_id']; 
    }

    if(!$tag) {
        return ["statuses" => []];
    }

    $client = new Client([
        'base_uri' => "https://$domain",
        'timeout'  => 2.0,
    ]);
    $resp = $client->get("/api/v1/timelines/tag/".ltrim($tag, '#'),[
        "headers" => [
            'Authorization' => 'Bearer ' . $token,        
            'Accept'        => 'application/json',
        ],
        "query" => $rv
    ]);
    $body = (string)($resp->getBody());
    $statuses = json_decode($body, true);
    return ["statuses" => array_map($mapTootDomain, $statuses)];
}

function buildUsernameWithDomain($acct, $domain) {
    return str_contains($acct, '@')?$acct:"$acct@$domain";
}

function getFullText($toot) {
    if ($toot['reblog']) {
        return $toot['reblog']['content'];
    }
    return $toot['content'];
}

function getRetweetedStatus($toot) {
    $reblog = $toot["reblog"]; 
    if (!$reblog) {
        return null;
    }
    return ['id_str' => strval($reblog['id'])];
}

function buildUser($account, $domain) {
    return [
        "id" => strval($account['id']),
        "screen_name" => buildUsernameWithDomain($account['acct'], $domain),
        "name" => $account['display_name'],
        "profile_image_url_https" => $account['avatar'],
        "url" => $account['url']
    ];
}

function mapToot($toot, $domain) {
    $new_obj = [
        'type' => 'Mastodon',
        'id' => strval($toot['id']),
        'from_user' => buildUsernameWithDomain($toot["account"]["acct"],$domain),
        'user' => buildUser($toot["account"], $domain),
        'from_user_id' => strval($toot["account"]["id"]),
        'in_reply_to_status_id' => $toot["in_reply_to_id"]?strval($toot["in_reply_to_id"]):null,
        'created_at' => $toot['created_at'],
        'full_text' => getFullText($toot),
        'retweeted_status' => getRetweetedStatus($toot),
        'url' => $toot['url'],
        'uri' => $toot['uri'],
    ];

    return $new_obj;
}

$cacheDriver = new Stash\Driver\Sqlite(array('path' => sys_get_temp_dir()."/polemictweet_cache.db"));
$cachePool = new Stash\Pool($cacheDriver);

/**
 * Check for a POSTed status message to send to Twitter
 */
if (!empty($_GET)
&& isset($_SESSION['SOCIAL_ACCESS_TOKEN'])) {

    $socialNetwork = isset($_GET['social_network'])?$_GET['social_network']:"Twitter";
    $request_vars = array_filter($_GET,fn ($key) => $key != 'social_network', ARRAY_FILTER_USE_KEY); 

    $itemCachePath="search/tweets?" . http_build_query($request_vars) . "_" . $_SESSION['SOCIAL_ACCESS_TOKEN'];

    $cachedStatusesResp = $cachePool->getItem($itemCachePath);

    $statusesStr = $cachedStatusesResp->get();

    if ($cachedStatusesResp->isMiss()) {
        $cachedStatusesResp->lock();
    
        
        $token = unserialize($_SESSION['SOCIAL_ACCESS_TOKEN']);
        $statuses = [];

        if ($socialNetwork == "Twitter") {
            $statuses = searchTwitter($token, $request_vars);    

        } else if ($socialNetwork == "Mastodon") {
            $statuses = searchMastodon($token, $request_vars, $_SESSION['SOCIAL_LOGIN_DOMAIN']);
        }
    
        $statusesStr = json_encode($statuses);

        $cachedStatusesResp->set($statusesStr)->expiresAfter(3);
        $cachePool->save($cachedStatusesResp);
    }

    echo($statusesStr);

} else {
    /**
     * Mistaken request? Some malfeasant trying something?
     */
    exit('Invalid tweet request. Oops. Sorry.');
}
?>