Twitter のアーカイブから削除候補の Tweets を抽出する補助ツールと削除するツール。
⚠️ 削除候補の抽出は基本的に過剰にかかるようになっています。細かいところは辞書などで調整してください。⚠️ Tweets の削除をすると復元はできないので、自己責任で削除してください。
- Twitter のデータアーカイブを使った削除の対応
- 自然言語、感情極性値ベースのフィルターでの絞り込みの対応
- 絞り込んだ結果のみを Twitter から削除
- 削除済みの履歴を使った絞り込みのキャッシュ
- Tweets を削除して、辞書を更新して、また絞り込みと何度も繰り返し処理ができる
- Node.js 18+
- 全ツイート履歴をダウンロードした zip ファイル
- Twitter V2 API のクライアントの API キー
Yarnを使ってインストールして、yarn bootstrapを実行してください。
yarn install
yarn bootstrap
Docker を利用して手元の環境を構築する場合、以下を実行します。
docker-compose up
docker-compose exec node yarn bootstrap
- docker での実行をする場合、これ以降全ての yarn コマンドの前に
docker-compose exec nodeを追加してください。 例えばyarn import-twitter-archivesはdocker-compose exec node yarn import-twitter-archivesとなります。
デバッグ:
docker-compose run --rm node ash
docker サーバー停止:
docker-compose down
次のステップで Tweets を削除します。
- Import Archive - Twitter のアーカイブから Tweets データの作成
- Detect Tweets - Tweets データをフィルタリングして削除候補の Tweets データを作成
- Delete Tweets - 削除対象の Tweets を削除
削除後は、data/deleted-twwets.txt に削除した Tweet の ID が記録されます。
すでに削除済みの場合は、次から無視されるので、2 ~ 3 を繰り返し実行できるようにデザインしています。
- 全ツイート履歴をダウンロードする方法を参考に Twitter のアーカイブをリクエストします
- Twitter のアーカイブ(
twitter-*.zip)をダウンロードして展開します - 中に含まれる
tweeet*.jsをtwitter-archives/ディレクトリにコピーします
twitter-archives/
├── tweet.js
├── tweet-part1.js
└── tweet-part2.js
-
次のコマンドを実行して、
tweet*.jsをインポートしてdata/tweets.jsonを作成しますyarn import-twitter-archives
yarn detect コマンドで、削除候補の Tweets データを data/will-delete-tweets.json として作成できます。
# all tweets
yarn detect
# 2015-01-01 ~ Now
$ yarn detect --fromDate 2015-01-01
# 2015-01-01 ~ 2016-01-01
$ yarn detect --fromDate 2015-01-01 --toDate 2016-01-01
yarn detectは --fromDate YYYY-MM-DD と --toDate YYYY-MM-DD で対象の Tweets の日付範囲を指定できます。
削除候補を推定する実装アルゴリズムは次の通りです。
config.jsでそれぞれの仕組みを利用するかの設定ができます。
📝 基本的に false positive を含んだ過剰な削除候補を作成します。削除候補をチェックして実際に削除する候補のみを data/will-delete-tweets.json に残してください。
ユーザー定義の辞書で削除候補に追加、削除できます。
次のファイルに定義することで、自動的にyarn detectが処理します。
削除しない Tweet のidを指定できます。
たとえば、https://twitter.com/twitter/status/123456765432 を削除対象から外す場合は次のように定義できます。
- 123456765432Tweets に含まれていたら削除対象とする辞書を定義します。 不許可リストには、文字列またはRegExp-like Stringベースの正規表現の配列を指定できます。
マッチ対象は tweeet.text の値のみです。
- /[亜-熙ぁ-んァ-ヶ]w+(\s|$)/ # これはwww みたいなやつ
- /(?<!く)ださい/ # くださいは対象外
- /これだけ知って(おけ|れば)/
- 嘘つき
- ぼったくりdisallow.yamlや textlint で NG となった場合にも、マッチした範囲がallow.yamlで許可されている場合は、削除対象から外せます。
許可リストには、文字列またはRegExp-like Stringベースの正規表現の配列を指定できます。
📝 allow.yamlで定義した辞書がtweet.text に含まれているから無条件に OK ではなく、あくまで NG となった範囲がが許可された範囲に含まれていれば、OK という実装になってる
- エディター # 特定の単語はOK
- /ECMAScript \d+/ # 正規表現
- /.*example\.com.*/ # example.com を含むならOK例) 次のようにdisallow.yamlで クソ という単語を NG としてしまうと、ダークソウルも NG となってしまう。
この場合は、allow.yaml に ダークソウル を定義することで、ダークソウルは許可される。
disallow.yaml:
- クソallow.yaml:
- ダークソウル実装の詳細:
disallow.yamlによって、2 から 3 までの範囲が NG として報告される。
allow.yamlによって、0 から 5 までの範囲はたとえ NG があっても例外として無視する。
|0|1|2|3|4|5|6|7|8|9|
------------------ 対象のTweetのtext
|ダ|ー|ク|ソ|ウ|ル|は|ゲ|ー|ム|
------------------ disallow.yamlの定義
|ク|ソ|
------------------ allow.yamlの定義
|ダ|ー|ク|ソ|ウ|ル|Steps:
allow-id.yamlchecktewet.iddisallow.yamlchecktweet.textallow.yamlcheck the disallowed word
yarn detectで作成した data/will-delete-tweets.json にかかれている Tweets を実際に削除します。
.env ファイルを作成し、Twitter V2 API のクライアントを作成して、そのクライアントの API Key と Access Token を入れて下さい。
TWITTER_APP_KEY="x"
TWITTER_APP_SECRET="x"
TWITTER_ACCESS_TOKEN="x"
TWITTER_ACCESS_SECRET="x"
yarn delete-tweets を実行すると、 data/will-delete-tweets.json に書かれた Tweets を 0.5 秒間隔で削除していきます。
yarn delete-tweets # It delete tweets actually
data/will-delete-tweets.json には削除したい対象だけを残してください。
Twitter の API を大量に叩く可能性があるので、自己責任で実行してください。
📝 削除した Tweets はdata/deleted-twwets.txtに ID が記録されます。
途中で削除を停止した場合も続きから実行できます。Rate Limit にかかった場合は自動で停止するつもりですが、そうじゃなかったら Issue を作ってください。
jq support JSONLD.
cat data/will-delete-tweets.json | jq -s ".[].text"Group by error's reason:
cat data/will-delete-tweets.json | jq -s "group_by(.reason)[] | {(.[0].reason): [.[] | .]}"Group by error's reason and count it
cat data/will-delete-tweets.json | jq -s "[group_by(.reason)[] | {reason: .[0].reason, count: length }] | sort_by(.count) | reverse"Show specific reason
cat data/will-delete-tweets.json | jq -s 'group_by(.reason)[] | select(.[0].reason | contains("理由")) | .[].text'Show favorited sort
cat data/will-delete-tweets.json | jq -s "[group_by(.reason)[] | {favorite_count: .[0].favorite_count, tweet: .[0].text, count: length, reason: .[0].reason }] | sort_by(.favorite_count) | reverse" | lessRemove specific errors
cat data/will-delete-tweets.json | jq -s -c 'group_by(.reason)[] | select(.[0].reason | contains("感情極性値") | not) | .[]' > data/will-delete-tweets.updated.jsonTest a text from stdin
echo "いやらしい文章" | yarn test-detect
# 感情極性値が0.3未満
# [ 'textlint-rule-ja-no-inappropriate-words: 不適切表現「いやらしい」が含まれています。' ]
See Releases page.
Install devDependencies and Run npm test:
npm test
Pull requests and stars are always welcome.
For bugs and feature requests, please create an issue.
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request :D
MIT © azu