{"id":1189,"date":"2014-11-10T09:53:21","date_gmt":"2014-11-10T14:53:21","guid":{"rendered":"http:\/\/jsomers.net\/blog\/?p=1189"},"modified":"2014-11-10T09:53:21","modified_gmt":"2014-11-10T14:53:21","slug":"docs-brief","status":"publish","type":"post","link":"https:\/\/jsomers.net\/blog\/docs-brief","title":{"rendered":"How I reverse-engineered Google Docs to play back any document&#8217;s keystrokes"},"content":{"rendered":"<p>If you&#8217;ve ever typed anything into a Google Doc, you can now play it back as if it were a movie &#8212; like traveling through time to look over your own shoulder as you write.<\/p>\n\n<p>This is possible because every document written in Google Docs since about May 2010 has a revision history that tracks every change, by every user, with timestamps accurate to the microsecond; these histories are available to anyone with &#8220;Edit&#8221;\n permissions; and I have written a piece of software that can find, decode, and rebuild the history for any given document.<\/p>\n\n<p>The details are <a href=\"http:\/\/features.jsomers.net\/how-i-reverse-engineered-google-docs\/\">here<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve ever typed anything into a Google Doc, you can now play it back as if it were a movie &#8212; like traveling through time to look over your own shoulder as you write. This is possible because every document written in Google Docs since about May 2010 has a revision history that tracks [&hellip;]<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1189","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/posts\/1189","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/comments?post=1189"}],"version-history":[{"count":3,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/posts\/1189\/revisions"}],"predecessor-version":[{"id":1192,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/posts\/1189\/revisions\/1192"}],"wp:attachment":[{"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/media?parent=1189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/categories?post=1189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jsomers.net\/blog\/wp-json\/wp\/v2\/tags?post=1189"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}