Twitter(現X)の前後ポストを表示する

    @@ -1,6 +1,6 @@ /* * @title Twitter(現X)の前後ポストを表示する - * @description 個別 Tweet の URL から前後 24 時間の投稿を RT を含めて表示する + * @description 個別 Tweet の URL から前後 1 時間の投稿を RT を含めて表示する * @include https://twitter.com/* * @license MIT License * @javascript_url @@ -8,19 +8,17 @@ const TWITTER_EPOCH = BigInt(1288834974657); -// 'YYYY-MM-DD_HH:mm:ss'形式で日付をフォーマット -// _HH:mm:ss 効かなくなってる?っぽいので YYYY-MM-DD だけにする +// 'YYYY-MM-DD_HH:mm:ss_JST'形式で日付をフォーマット const formatTwitterDate = (date) => { const pad2 = (n) => n.toString().padStart(2, '0'); const year = date.getFullYear(); const month = pad2(date.getMonth() + 1); const day = pad2(date.getDate()); - // const hour = pad2(date.getHours()); - // const minute = pad2(date.getMinutes()); - // const second = pad2(date.getSeconds()); - // return `${year}-${month}-${day}_${hour}:${minute}:${second}`; - return `${year}-${month}-${day}`; + const hour = pad2(date.getHours()); + const minute = pad2(date.getMinutes()); + const second = pad2(date.getSeconds()); + return `${year}-${month}-${day}_${hour}:${minute}:${second}_JST`; } // Snowflake ID 文字列を受け取り、前後 60 分の since, until を返す @@ -33,11 +31,8 @@ const timestamp = Number((snowflake >> BigInt(22)) + TWITTER_EPOCH); return { - // since: formatTwitterDate(new Date(timestamp - 60 * 60 * 1000)), // 60 分前 - // until: formatTwitterDate(new Date(timestamp + 60 * 60 * 1000)), // 60 分後 - // _HH:mm:ss 効かなくなってる?っぽいので前後 1 日にする - since: formatTwitterDate(new Date(timestamp - 24 * 60 * 60 * 1000)), // 1 日前 - until: formatTwitterDate(new Date(timestamp + 24 * 60 * 60 * 1000)), // 1 日後 + since: formatTwitterDate(new Date(timestamp - 60 * 60 * 1000)), // 60 分前 + until: formatTwitterDate(new Date(timestamp + 60 * 60 * 1000)), // 60 分後 }; }
  • /*
     * @title Twitter(現X)の前後ポストを表示する
     * @description 個別 Tweet の URL から前後 1 時間の投稿を RT を含めて表示する
     * @include https://twitter.com/*
     * @license MIT License
     * @javascript_url
     */
    
    const TWITTER_EPOCH = BigInt(1288834974657);
    
    // 'YYYY-MM-DD_HH:mm:ss_JST'形式で日付をフォーマット
    const formatTwitterDate = (date) => {
      const pad2 = (n) => n.toString().padStart(2, '0');
    
      const year = date.getFullYear();
      const month = pad2(date.getMonth() + 1);
      const day = pad2(date.getDate());
      const hour = pad2(date.getHours());
      const minute = pad2(date.getMinutes());
      const second = pad2(date.getSeconds());
      return `${year}-${month}-${day}_${hour}:${minute}:${second}_JST`;
    }
    
    // Snowflake ID 文字列を受け取り、前後 60 分の since, until を返す
    const getSearchRange = (snowflakeStr) => {
      const snowflake = BigInt(snowflakeStr);
      // 41 bits: millisec from TWITTER_EPOCH
      // 10 bits: worker_id
      // 12 bits: sequence number
      // なので 22 bit 右シフトする
      const timestamp = Number((snowflake >> BigInt(22)) + TWITTER_EPOCH);
    
      return {
        since: formatTwitterDate(new Date(timestamp - 60 * 60 * 1000)), // 60 分前
        until: formatTwitterDate(new Date(timestamp + 60 * 60 * 1000)), // 60 分後
      };
    }
    
    const main = () => {
      const match = location.href.match(/https:\/\/twitter\.com\/(?<name>[^/]+)\/status\/(?<snowflake>\d+)/);
      if (!match) {
        alert('このページは Twitter の個別 Tweet ではありません');
        return;
      }
      const range = getSearchRange(match.groups.snowflake);
      const query = `from:${match.groups.name} since:${range.since} until:${range.until} include:nativeretweets`;
      location.href = `https://twitter.com/search?f=live&q=${encodeURIComponent(query)}`;
    }
    
    main();
    
  • Permalink
    このページへの個別リンクです。
    RAW
    書かれたコードへの直接のリンクです。
    Packed
    文字列が圧縮された書かれたコードへのリンクです。
    Userscript
    Greasemonkey 等で利用する場合の .user.js へのリンクです。
    Loader
    @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
    Metadata
    コード中にコメントで @xxx と書かれたメタデータの JSON です。