過去ツイートのアーカイブをダウンロードしたので中身のファイルを確認してみた
ツイッターには過去ツイートのアーカイブを取得する機能があります。
アーカイブ取得手順についての紹介記事は見かけるものの、内容についての説明はあまり見かけなかったので分かる範囲で記事にまとめました。
過去ツイートのアーカイブを取得する
ダウンロード方法については多数の記事が上がっているため、ここでは公式の手順リンク紹介にとどめます。
自分はアーカイブのリクエストを送ってから、半日程度でダウンロード可能になりました。
アーカイブのファイルサイズは解凍前が131MB、解凍後が172MBでした。
(ツイート数は2,113、画像ツイートはそこそこ、動画ツイートはほぼなし)
アーカイブの概要
ファイル構成
twitter-yyyy-MM-dd-log/
├ assets/ : 各種資源格納フォルダ
├ data/ : アカウント固有のツイートやプロフィールデータ等格納フォルダ
└ Your archive.html : アーカイブ表示用HTMLファイル
Your archive.html
Your archive.htmlファイルではassetsフォルダやdataフォルダを読み込んで、アーカイブファイルを閲覧するためのUIを提供してくれます。
「アカウント」タブ
ユーザー名や自己紹介、フォロワー数等のアカウント関連の情報が一通り閲覧できます。
アカウント作成日や作成時のIPアドレス、過去のユーザー名の変更履歴、ツイッターと連携しているアプリの一覧、アカウントアクセス履歴など普段はあまり見かけないような情報も確認可能です。
「ツイート」タブ
以下の4カテゴリごとにツイートの表示と検索が可能です。
なお、各ツイートには「Twitterで表示」というリンクが付与されており、クリックするとアーカイブではない実際のツイートへ飛びます。
- ツイート : 通常のツイートと引用リツイートを表示。本家のUIとは違ってセルフリプライや普通のリツイートは表示されない
- 返信 : リプライをすべて表示。リプライ先のツイートは表示されない。また、セルフリプライの場合は宛先が表示されないが、他人へのリプライは宛先が表示される
- リツイート : リツイートしたツイートの本文を表示。引用リツイートはここには表示されない。リツイート元の画像等は反映される場合とされない場合があるっぽいが原因は未確認
- コミュニティのツイート : コミュニティ機能を使ったことがないため不明
「いいね」タブ
いいねしたツイートの文面が表示されます。文面のみで画像やアカウント名などは表示されません。自分の環境だと件数が多すぎるためか80件程度読み込んだところでエラーになります
「ダイレクトメッセージ」タブ
DMの一覧が表示されます。相手のアカウントは確認できません。また、ツイートとは違いリンクからツイッターに飛ぶこともできません
その他のタブ
- セキュリティ : ミュートとブロックの一覧
- カスタマイズ : 性別や年代の推測情報やログイン場所など。おそらくターゲッティング広告のために収集しているデータ?
- 広告 : 「Twitterに表示された可能性のある広告です。」とのことだが自分は何も表示されず
- リスト : 作成、登録、追加されたリストの一覧
- モーメント: すでに削除されたモーメント機能に関するものらしい。自分は使ったことがないが、過去に使ったことがある人は何か表示されるかも
HTMLコード
HTMLの中身では、基本的に./data/manifest.js
を読み取って情報を表示しているようです。
Your archive.htmlのコード
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width,initial-scale=1" charset="utf-8">
<title>Your Twitter Data</title>
<style>
@media screen and (min-width: 450px) {
#mobile-error {
display: none;
}
}
#manifest-error {
display: none;
}
</style>
<link rel="icon" href="./assets/images/favicon.ico">
</head>
<body>
<div id="root"></div>
<div id="manifest-error">
<h3>Something went wrong, but don’t fret — let’s give it another shot</h3>
<p>
You need to unzip your entire archive, not just individual folders, in order to view them here. If you keep experiencing errors, please <a href="https://help.twitter.com/forms/privacy" target="_blank">fill out this form.</a>
</p>
</div>
<div id="mobile-error">
<h3>Your archive isn’t available here.</h3>
<p>
You need to view this on a desktop browser in order to see your archive.
</p>
</div>
<script>
function showManifestError() {
document.getElementById('root').style.display = 'none';
document.getElementById('manifest-error').style.display = 'block';
}
</script>
<script src="./data/manifest.js" onerror="showManifestError()"></script>
<script src="assets/js/runtime.9662ea169e7e46b859ee.js"></script>
<script src="assets/js/modules.9072ed6e90fe38c485fe.js"></script>
<script src="assets/js/i18n.e27e67d39fcc91627cab.js"></script>
<script src="assets/js/main.0506aebee0a5b8f83a32.js"></script>
</body>
</html>
ファイルの中身
dataフォルダのファイル構成
ファイルが多くてキリがないので一部のみ紹介。
twitter-yyyy-MM-dd-log/data/
├ profile_media/ : プロフィールとヘッダー画像を格納するフォルダ
├ tweets_media/ : ツイート、リツイートに添付の画像、動画ファイル格納フォルダ
├ README.txt : dataフォルダの各ファイル説明を記載
├ account.js : メールアドレス、ID、ユーザー名などを格納
├ ad-engagements.js : アカウントがエンゲージしたプロモツイートのデータらしい
├ manifest.js : dataフォルダで最初に読み込まれるファイル。ここから各jsを読み込む
├ like.js : いいねしたツイートの本文とID、URLを格納
└ tweets.js : ツイート、リプライ、リツイートなどの情報を格納
普段目にしないようなデータまで格納されていますが、現状ブックマークの情報はダウンロードできないようです。
README.txt
dataフォルダ内の各ファイルの説明を記載。まずはここを読もう。
account.js
「account.js」に限らず、data内のjsファイルは以下のようにオブジェクト形式でデータを保管しています。
オブジェクトの各項目の詳細はREADMEを参照。
account.jsのコード
window.YTD.account.part0 = [
{
"account" : {
"email" : "xxxxxxxx@xxxxxxx.com",
"createdVia" : "oauth:xxxxxx",
"username" : "pessi_ink",
"accountId" : "xxxxxxxxxxxxxxxxxxx",
"createdAt" : "2018-03-15T15:03:28.897Z",
"accountDisplayName" : "ぺし"
}
}
]
ad-engagements.js
ターゲッティング広告のメタデータが格納されています。
「targetingType」を見るとどんな層に向けて広告を打っているかが見えて面白いです。
性別や年齢、OS、どんなアプリを利用しているかなどの情報をもとにしているらしい。
ad-engagements.jsのコード(一部抜粋)
window.YTD.ad_engagements.part0 = [
{
"ad" : {
"adsUserData" : {
"adEngagements" : {
"engagements" : [
{
"impressionAttributes" : {
"deviceInfo" : {
"osType" : "Ios",
"deviceId" : "2eVW2/fWZAazjwP/uvHAa4qkFW/vxfWcs2GVKmq/Lvo="
},
"displayLocation" : "TimelineHome",
"promotedTweetInfo" : {
"tweetId" : "1818210512460738903",
"tweetText" : "【思い通りになんかさせない】\n前世の記憶を取り戻した私に、\n再び番候補に選ばれたという招待状が届くが",
"urls" : [ ],
"mediaUrls" : [ ]
},
"advertiserInfo" : {
"advertiserName" : "コミックシーモアPR",
"screenName" : "@comic_cmoa_pr3"
},
"matchedTargetingCriteria" : [
{
"targetingType" : "Gender",
"targetingValue" : "Women"
},
{
"targetingType" : "Age",
"targetingValue" : "18 and up"
},
{
"targetingType" : "Platforms",
"targetingValue" : "iOS"
},
{
"targetingType" : "Locations",
"targetingValue" : "Japan"
}
],
"impressionTime" : "2024-09-10 02:35:59"
},
"engagementAttributes" : [
{
"engagementTime" : "2024-09-10 02:39:18",
"engagementType" : "ChargeableImpression"
}
]
}
]
}
}
}
}
]
like.js
いいねしたツイートの本文とID、URLが格納されています。
HTMLでいいね欄を表示しようとするとエラーになる可能性があるため、jsファイルから見たほうがいいかもしれない
like.jsのコード(一部抜粋)
window.YTD.like.part0 = [
{
"like" : {
"tweetId" : "1779797519788351508",
"fullText" : "【4月18日(木)発売】『コミック百合姫6月号』は、溺愛され系異世界召喚ハーレムラブコメ「現実世界でも幸せにしてくださいね?」が巻頭カラーで開幕!… https://t.co/AUXVvsa8yr",
"expandedUrl" : "https://twitter.com/i/web/status/1779797519788351508"
}
},
{
"like" : {
"tweetId" : "1779751666851721637",
"fullText" : "ロッテガーナチョコレートとのコラボレーション!\n「シロノワール ガーナミルク」をはじめ4 種の商品を4 月23 日 火 より季節限定で販売開始🎉\n長年愛され続ける、「コメダ珈琲店」と「ガーナチョコレート」のコラボレーションが実現\nコメダ珈琲店は1968… https://t.co/4UfuSbmBgE",
"expandedUrl" : "https://twitter.com/i/web/status/1779751666851721637"
}
},
]
tweets.js
すべてのツイート、リツイートなどがこのファイルに格納されています。
こうして見ると、たった一つのツイートにも結構な数のメタデータが含まれているっぽい。
有料プランに入ってないのでREADMEを読むまでツイート修正に回数制限があるのを知りませんでした。
「この JSON ファイルには、削除されていない利用可能なツイートが含まれており、該当する場合は編集されたツイートも含まれます。ユーザーはツイートを最大 5 回編集できます。そのため、最大 5 つの編集済みツイートには固有の「editTweetIds」があり、すべて「initialTweetID」で接続されています。」
tweets.jsのコード(一部抜粋)
window.YTD.tweets.part0 = [
{
"tweet" : {
"edit_info" : {
"initial" : {
"editTweetIds" : [
"1676561267723747329"
],
"editableUntil" : "2023-07-05T12:58:49.000Z",
"editsRemaining" : "5",
"isEditEligible" : true
}
},
"retweeted" : false,
"source" : "<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>",
"entities" : {
"hashtags" : [ ],
"symbols" : [ ],
"user_mentions" : [ ],
"urls" : [ ]
},
"display_text_range" : [
"0",
"57"
],
"favorite_count" : "1",
"id_str" : "1676561267723747329",
"truncated" : false,
"retweet_count" : "0",
"id" : "1676561267723747329",
"created_at" : "Wed Jul 05 11:58:49 +0000 2023",
"favorited" : false,
"full_text" : "ネットショッピングにありがちな「最大70%OFF‼️(上限1,000円)」みたいなやつウザいからはやく規制しなさい",
"lang" : "ja"
}
}
]
manifest.js
このファイルを起点に上記のjsファイル達が読み込まれるようです。
ソースまでは確認していませんが、最低限「archiveInfo」の項目だけがあればhtml動作するようです。
window.__THAR_CONFIG = {
"archiveInfo" : {
"sizeBytes" : "145105637",
"generationDate" : "2024-10-20T07:30:21.997Z",
"isPartialArchive" : false,
"maxPartSizeBytes" : "53687091200"
},
}
もしアーカイブを他人に共有したい場合(そんなケースがあるかは知りませんが)、そのまま公開するとDMの内容や鍵垢のいいねまで見えてしまうので、manifest.jsで表示内容を制御可能です。
例えばツイートだけを表示したい場合には以下のように編集すれば問題ないかと思います。
window.__THAR_CONFIG = {
"archiveInfo" : {
"sizeBytes" : "145105637",
"generationDate" : "2024-10-20T07:30:21.997Z",
"isPartialArchive" : false,
"maxPartSizeBytes" : "53687091200"
},
"dataTypes" : {
"account" : {
"files" : [ {
"fileName" : "data/account.js",
"globalName" : "YTD.account.part0",
"count" : "1"
} ]
},
"profile" : {
"mediaDirectory" : "data/profile_media",
"files" : [ {
"fileName" : "data/profile.js",
"globalName" : "YTD.profile.part0",
"count" : "1"
} ]
},
"profileMedia" : {
"mediaDirectory" : "data/profile_media"
},
"tweets" : {
"mediaDirectory" : "data/tweets_media",
"files" : [ {
"fileName" : "data/tweets.js",
"globalName" : "YTD.tweets.part0",
"count" : "2113"
} ]
},
"tweetsMedia" : {
"mediaDirectory" : "data/tweets_media"
},
}
}
読み込まない不要なファイルも削除しましょう。
まとめ
以上、ツイートのアーカイブデータについてわかる範囲でまとめてみました。
APIを利用するような方には特に物珍しくもないのかもしれませんが、ツイートのメタデータやターゲッティング広告の中身まで見れるのは面白いと思います。
昨今ツイッターからの移行を考えている人も結構見かけるので、そういう方は移行前にバックアップを残しておくのが吉かと思います。
過去に投稿した画像などのメディアファイルがすべて一つのフォルダにまとまっているのは非常に便利でした。
また、ツイートのデータはjsのオブジェクトとして保管されているので、適当なスクリプトでデータを拾えば過去ツイートの移行も簡単にできるかと思います。
Discussion