相手の「n年前」のツイートを一発表示する（語句検索も）

# 動機
- いろんな人の「n年前の今日」のツイートを見たい
- 故人の「5年前の今日」等をこまめに追えればグリーフケアの一助になるかも


# コード

ブクマ用／一行圧縮（同タブ表示）　※ブックマークのURL欄にコピペ

```javascript:
javascript:(()=>{const defo=3;const input=window.prompt('how many years ago?%27,defo)??!1;if(input===!1)return;const url=decodeURIComponent(location.href);let userName=%27livedoornews%27;const r1=/^https:\/\/(mobile.)?twitter.com\/(\w*)(\/.*|\?.*)?$/;const m1=url.match(r1)??!1;if(m1[2]!==%27search%27){switch(m1[2]){case undefined:case %27i%27:case %27home%27:case %27explore%27:case %27messages%27:case %27notifications%27:break;default:userName=m1[2];break}}else{const r2=/^https:\/\/(mobile.)?twitter.com\/search\?q=\(from:(\w*)\).*?$/;const m2=url.match(r2)??!1;if(m2[2]!==undefined){userName=m2[2]}} const r3=/^1\d$|^[1-9]$/;const isYear=new RegExp(r3).test(input);let encodedQuery=String;if(!isYear){encodedQuery=encodeURIComponent(`(from:${userName})${input}`)}else{const howManyYear=Number(input);let now=new Date();const h=now.getHours();const mi=now.getMinutes();const sec=now.getSeconds();let until=new Date(now.setFullYear(now.getFullYear()-howManyYear));const uy=until.getFullYear();const um=until.getMonth()+1;const ud=until.getDate();let since=new Date(until.setMonth(until.getMonth()-1));const sy=since.getFullYear();const sm=since.getMonth()+1;const sd=since.getDate();const untilDate=`${uy}-${um}-${ud}_${h}:${mi}:${sec}`;const sinceDate=`${sy}-${sm}-${sd}_${h}:${mi}:${sec}`;encodedQuery=encodeURIComponent(`(from:${userName})(until:${untilDate}_JST)(since:${sinceDate}_JST)`)} const jumpTo=`https://twitter.com/search?q=${encodedQuery}&src=typed_query&f=live`;window.location.href=jumpTo})()
```

ブクマ用／一行圧縮（別タブ表示）

```javascript:
javascript:(()=>{const defo=3;const input=window.prompt('how many years ago?%27,defo)??!1;if(input===!1)return;const url=decodeURIComponent(location.href);let userName=%27livedoornews%27;const r1=/^https:\/\/(mobile.)?twitter.com\/(\w*)(\/.*|\?.*)?$/;const m1=url.match(r1)??!1;if(m1[2]!==%27search%27){switch(m1[2]){case undefined:case %27i%27:case %27home%27:case %27explore%27:case %27messages%27:case %27notifications%27:break;default:userName=m1[2];break}}else{const r2=/^https:\/\/(mobile.)?twitter.com\/search\?q=\(from:(\w*)\).*?$/;const m2=url.match(r2)??!1;if(m2[2]!==undefined){userName=m2[2]}} const r3=/^1\d$|^[1-9]$/;const isYear=new RegExp(r3).test(input);let encodedQuery=String;if(!isYear){encodedQuery=encodeURIComponent(`(from:${userName})${input}`)}else{const howManyYear=Number(input);let now=new Date();const h=now.getHours();const mi=now.getMinutes();const sec=now.getSeconds();let until=new Date(now.setFullYear(now.getFullYear()-howManyYear));const uy=until.getFullYear();const um=until.getMonth()+1;const ud=until.getDate();let since=new Date(until.setMonth(until.getMonth()-1));const sy=since.getFullYear();const sm=since.getMonth()+1;const sd=since.getDate();const untilDate=`${uy}-${um}-${ud}_${h}:${mi}:${sec}`;const sinceDate=`${sy}-${sm}-${sd}_${h}:${mi}:${sec}`;encodedQuery=encodeURIComponent(`(from:${userName})(until:${untilDate}_JST)(since:${sinceDate}_JST)`)} const jumpTo=`https://twitter.com/search?q=${encodedQuery}&src=typed_query&f=live`;window.open(jumpTo,'_blank','noreferrer')})()
```

全体／圧縮前

```javascript:

function yearsAgoTweet()
{
  const defo = 3;                                                     // 入力欄の初期値
  const input = window.prompt('how many years ago?', defo) ?? false;  // 入力欄を表示、OK押下で代入
  if(input === false) return;                                         // キャンセル押下なら終了

  const url = decodeURIComponent(location.href);  // 現在のURL
  let userName = 'livedoornews';                  // regex1か2でユーザー名と思われる部分があれば上書き

  const r1 = /^https:\/\/(mobile.)?twitter.com\/(\w*)(\/.*|\?.*)?$/;  // regex1
  const m1 = url.match(r1) ?? false;  // match1。「twitter.com/」の次の文字列がm1[2]に入る

  //  m1に応じuserNameを上書き
  if (m1[2] !== 'search') { // 「search」の場合のみelse句で「(from:~)」の文字列抽出を試行

    // 明らかにユーザー名でない値は代入しない
    switch(m1[2]) {
      case undefined:
      case 'i':
      case 'home':
      case 'explore':
      case 'messages':
      case 'notifications':
        break;
      default: // 上記以外なら代入
        userName = m1[2];
        break;
    }

  } else {

    // URLが「search?〜」の場合。「from:~」があればuserNameに代入
    const r2 = /^https:\/\/(mobile.)?twitter.com\/search\?q=\(from:(\w*)\).*?$/;
    const m2 = url.match(r2) ?? false;  // 「search?q=(from:~)」の「~」がm2[2]に入る
    if (m2[2] !== undefined) {
      userName = m2[2];                 // from:~が存在した場合のみ初期値を上書き
    }

  }

  // 入力値が「1~19」か否か
  const r3 = /^1\d$|^[1-9]$/;                   // regex3
  const isYear = new RegExp(r3).test(input);    // 半角「1~19」ならtrue、それ以外ならfalse
  let encodedQuery = String;                    // 最終的なURに結合する検索文を代入

  if(!isYear) {
    // 語句サーチの場合(from:~, term)
    encodedQuery = encodeURIComponent(`(from:${userName})${input}`); // 結合
  } else {
    // n年前サーチの場合（from:~, until:~, since:~）
    const howManyYear = Number(input);  // 数値型にキャスト

    let now = new Date();               // 現在日時分秒
    const h = now.getHours();           // 時
    const mi = now.getMinutes();        // 分
    const sec = now.getSeconds();       // 秒

    let until = new Date(now.setFullYear(now.getFullYear() - howManyYear)); // n年前の同日
    const uy = until.getFullYear();     // 年
    const um = until.getMonth() + 1;    // 月
    const ud = until.getDate();         // 日

    let since = new Date(until.setMonth(until.getMonth() - 1)); // n年前の1ヵ月前
    const sy = since.getFullYear();     // 年
    const sm = since.getMonth() + 1;    // 月
    const sd = since.getDate();         // 日

    const untilDate = `${uy}-${um}-${ud}_${h}:${mi}:${sec}`;// この日時までのツイートを検索
    const sinceDate = `${sy}-${sm}-${sd}_${h}:${mi}:${sec}`;// この日時からのツイートを検索
    encodedQuery = encodeURIComponent(`(from:${userName})(until:${untilDate}_JST)(since:${sinceDate}_JST)`);// 結合
  }

  const jumpTo = `https://twitter.com/search?q=${encodedQuery}&src=typed_query&f=live`;// 最終的なURL
  window.location.href = jumpTo;                // ページ遷移
  // window.open(jumpTo,'_blank','noreferrer'); // ページ遷移（別タブ表示）
}

```

# 説明
- ブラウザでのみ使用可能です。　※safari,chrome等
スマホでは実行時、強制的にブラウザ版からアプリ版Twitterへ遷移させられます。
別タブ表示の方を選ぶと防げるかもしれません。

- 実行すると初期値「3」の入力ダイアログが表示されます。
初期値を変更したい場合は、ブクマ冒頭「defo=3」の値を変更して下さい。
 
- 「1~19以外」を入力時は語句サーチとみなし、「(from:userName)」と合わせて過去ツイート検索を行います。
 
- 「1~19」(※半角)を入力時はn年前サーチとみなし、入力された値だけ年数(西暦)をさかのぼります。
※ 西暦以外は同じ月日・時分秒で「until:~」検索結果を表示します
※ 0埋めは検索に支障なかったため、していません。「2020-1-2_7:8:9_JST」などで検索されます。／→1月2日7時8分9秒

- 誰かのツイートかプロフを表示中の場合のみ、「twitter.com/」に続く文字列をuserNameとして「from:~」に代入します
 
- 「home／explore／search／notifications」等、明らかにユーザー名でないものは代入せず、初期値「lived\*\*rnews」でfrom検索します

- 毎日欠かさずツイートしているアカウントは少ないため、「since:~」を1ヵ月前に設定して幅を持たせています
 
- 昔の公式リツイートは検索できません
※ 検索可能な公式リツイートは直近1週間程度（「include:nativeretweets」）


---


### ブックマークレットの利用方法

https://qiita.com/aqril_1132/items/b5f9040ccb8cbc705d04

:::note info
Android版Chromeはブックマークのタップでは動作しないようです。
アドレスバーに「かこつい」等の（自分で命名した）簡易ブクマ名を入力し、
候補として表示された当該ブクマをタップすると実行できます。
:::

- - -

自分でいっぱい使っています。
では！🕊

https://twitter.com/soresoja/status/1540707712920854528