• Stars
    star
    187
  • Rank 206,464 (Top 5 %)
  • Language
    PHP
  • Created over 10 years ago
  • Updated about 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Archive your iMessage history to HTML, CSV or SQL

iMessage Archive

Archives all your iMessage history from the chat.db file.

Currently group conversations are not supported.

Contacts

If you don't already have a contacts.txt file, you'll need to create one. This way the messages will be stored in folders by peoples' names rather than by their phone numbers.

The very first thing in the contacts.txt must be your own iMessage ID and name. This is used to set the name for your own sent messages in the logs.

First run php contacts.php which will output all the contacts listed in the chat log. Fill in this file with peoples' names so that the chat logs look a little better. The first time you run it, you can run the script and output the txt file in one command:

php contacts.php >> contacts.txt
+15031234567 Your Name
+15035551212 Cool Dude
[email protected] Cool Dude

You can have multiple entries per person, and they will be combined into a single log folder with that person's name.

Running php contacts.php subsequently will output only new contacts that were not yet in the file.

Export Formats

Running php archive.php will export to HTML files sorted by contact.

Running php export-csv.php will export to a single CSV file. See below for the structure of the file.

HTML Folder Structure

Messages are saved in separate files per month under a folder of each person's name. If you don't have an entry for them in your contacts.txt file, the folder name will be their iMessage ID (phone number or email address).

Photos that were sent in messages will also be archived in the folder.

messages/

# Individual chats
messages/Cool Dude/
messages/Cool Dude/2014-04.html
messages/Cool Dude/2014-05.html
messages/Cool Dude/2014-05/photo.jpg

HTML Log Files

Messages are stored as a minimal HTML page. Structured data is available by parsing out the microformats markup.

Each message is an h-entry containing the author, timestamp and text of the message. You can parse these into a JSON structure using a Microformats parser

<div class="h-entry">
  <time class="dt-published" datetime="2014-05-01T10:48:00+00:00">2014-05-01 10:48:00</time> 
  <a href="sms:+15035551212" class="p-author h-card">Cool Dude</a>
  <span class="e-content p-name">Message text here</span>
</div>
<div class="h-entry">
  <time class="dt-published" datetime="2014-05-01T10:49:00+00:00">2014-05-01 10:49:00</time> 
  <a href="mailto:[email protected]" class="p-author h-card">Aaron Parecki</a> 
  <span class="e-content p-name">Message text here</span>
</div>
{
  "items": [
    {
      "type": ["h-entry"],
      "properties": {
          "author": [
              {
                  "type": ["h-card"],
                  "properties": {
                      "name": ["Cool Dude"],
                      "url": ["sms:+15035551212"]
                  },
                  "value": "Cool Dude"
              }
          ],
          "name": ["Message text here"],
          "published": ["2014-05-01T10:48:00+00:00"],
          "content": [
              {
                  "html": "Message text here",
                  "value": "Message text here"
              }
          ]
      }
    },
    {
      "type": ["h-entry"],
      "properties": {
          "author": [
              {
                  "type": ["h-card"],
                  "properties": {
                      "name": ["Aaron Parecki"],
                      "url": ["mailto:[email protected]"]
                  },
                  "value": "Aaron Parecki"
              }
          ],
          "name": ["Message text here"],
          "published": ["2014-05-01T10:49:00+00:00"],
          "content": [
              {
                  "html": "Message text here",
                  "value": "Message text here"
              }
          ]
      }
    }
  ]
}

Photos in the message thread are also included in the export and are stored in a subfolder with the same name as the file. They are embedded in the HTML with an img tag so they will be rendered by browsers.

CSV Log File

Only one file is created when exporting as csv. The csv file will have the following columns:

Timestamp, Date, Time, From, From Name, To, To Name, Message, Emoji, Attachments
  • Timestamp: The unix timestamp of the message (seconds since 1970-01-01)
  • Date: The date will be in the format YYYY-mm-dd
  • Time: The time will be HH:mm:ss
  • From, To: The iMessage ID of the sender and recipient
  • From Name, To Name: The name of the person as defined in your contacts.txt file (see above)
  • Message: This is the actual text of the message
  • Emoji: The number of emoji characters in the message
  • Attachments: The number of attachments (usually photos) sent in the message

The messages are usually in chronological order, but because of delays in when your computer actually receives the messages, they might be slightly out of order.

SQL Database

If you want to quickly query your data it may be faster to load the messages into a SQL database so you can write SQL queries.

First create a table with the following SQL:

CREATE TABLE `messages` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `timestamp` int(11) DEFAULT NULL,
  `date` date DEFAULT NULL,
  `time` time DEFAULT NULL,
  `from` varchar(255) DEFAULT NULL,
  `from_name` varchar(255) DEFAULT NULL,
  `to` varchar(255) DEFAULT NULL,
  `to_name` varchar(255) DEFAULT NULL,
  `message` text CHARACTER SET utf8mb4,
  `num_emoji` int(11) DEFAULT NULL,
  `num_attachments` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `from,to` (`from`,`to`),
  KEY `timestamp` (`timestamp`),
  KEY `date` (`date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

To import into the database, first make sure you copy config-db.sample.php to config-db.php and define your own database credentials. Then run:

php export-sql.php

Here are some example queries you can run!

Who sends me the most messages in the past year?

SELECT from_name, COUNT(1) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY from_name
ORDER BY COUNT(1) DESC

(The top result will be you, so just ignore that)

Who do I send the most messages to?

SELECT to_name, COUNT(1) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY to_name
ORDER BY COUNT(1) DESC

Most contacted people in the past year

SELECT IF(from_name="Aaron Parecki", to_name, from_name) AS name, COUNT(1) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY IF(from_name="Aaron Parecki", to_name, from_name)
ORDER BY COUNT(1) DESC;

Obviously you should replace my name with yours. This will count both sent and received messages.

Number of messages sent and received per day

SELECT date, COUNT(1) AS num
FROM messages
GROUP BY date

Days with the most messages sent in the past year

SELECT date, COUNT(1) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY date
ORDER BY COUNT(1) DESC

Number of messages per month

SELECT date, COUNT(1) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY YEAR(date), MONTH(date)
ORDER BY date DESC

Number of emoji used per month

SELECT date, SUM(num_emoji) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
GROUP BY YEAR(date), MONTH(date)
ORDER BY date DESC

Who sent me the most emoji in the past year?

SELECT from_name, SUM(num_emoji) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
  AND num_emoji > 0
GROUP BY from_name
ORDER BY SUM(num_emoji) DESC

Who did I send the most emoji to in the past year?

SELECT to_name, SUM(num_emoji) AS num
FROM messages
WHERE date > "2013-07-07"
  AND date < "2014-07-07"
  AND num_emoji > 0
GROUP BY to_name
ORDER BY SUM(num_emoji) DESC

Do you send or receive more emoji?

SELECT * FROM
(SELECT "received" AS type, SUM(num_emoji) AS num
FROM messages
WHERE to_name = "Aaron Parecki") AS received
UNION
(SELECT "sent" AS type, SUM(num_emoji) AS num
FROM messages
WHERE from_name = "Aaron Parecki")

What hour is most active?

SELECT HOUR(DATE_ADD(time, INTERVAL 24-7 HOUR)) % 24 AS local_hour, COUNT(1) AS num
FROM messages
GROUP BY HOUR(time)
ORDER BY time

Change the -7 to your local timezone offset. Also this ignores DST so that could use some work.

More Repositories

1

webmention.io

Easily enable webmentions and pingbacks on any web page
Ruby
681
star
2

Overland-iOS

πŸ“Œ GPS logger for iOS devices
Objective-C
595
star
3

oauth.net

πŸ”’ The oauth.net website. Feel free to send pull requests with updates.
PHP
267
star
4

Google-Voice-PHP-API

Unmaintaned: Please do not contact me with support requests. If this no longer works, it's because Google Voice changed their systems. I will accept pull requests that fix things. Check out http://twilio.com for a much better API for sending and receiving SMSs.
PHP
229
star
5

IndieAuth.com

This service is being discontinued in favor of indielogin.com
Ruby
182
star
6

sign-in-with-apple-example

Sample code for the Sign in with Apple API
PHP
155
star
7

indielogin.com

Sign in with your domain name
JavaScript
131
star
8

emoji-detector-php

This library will find all emoji in an input string and return information about each emoji character.
PHP
126
star
9

live-chat-overlay

Restyle the YouTube "popout chat" window so you can key it over a video to show comments on a livestream
JavaScript
124
star
10

pkce-vanilla-js

A demonstration of the OAuth PKCE flow in plain JavaScript
HTML
122
star
11

Compass

Compass is a GPS tracking server that stores data in flat files.
JavaScript
111
star
12

Quill

πŸ–‹ A Micropub client for creating posts
PHP
111
star
13

Bootstrap-Skin

Bootstrap Skin for MediaWiki. Bootstrap is an excellent toolkit by Twitter. This is a MediaWiki skin based off of that template.
JavaScript
100
star
14

OwnYourGram

πŸ“· Save your Instagram photos to your own website!
PHP
92
star
15

sample-oauth2-client

Sample OAuth2 client using the GitHub API
PHP
86
star
16

XRay

X-Ray returns structured data from any URL
PHP
85
star
17

Nautilus

Turn your website into an ActivityPub profile
PHP
76
star
18

Meetable

a minimal website for posting events
PHP
70
star
19

Aperture

Aperture is a Microsub server. Currently in beta.
PHP
67
star
20

Device-Flow-Proxy-Server

Add the OAuth 2.0 Device Flow to any OAuth server
PHP
66
star
21

Monocle

Monocle is a reader app that talks to a Microsub server
Sass
47
star
22

quick-php-authentication

Add Authentication to your PHP App in 5 Minutes!
PHP
44
star
23

Watchtower

🏰 a minimal API for watching web pages for changes, roughly speaks the WebSub protocol
PHP
43
star
24

IndieNews

πŸ“° News aggregator for IndieWeb-related posts
PHP
35
star
25

Slack-IRC-Gateway

Bridge Slack rooms to IRC channels
JavaScript
34
star
26

atem-tally-controller

C++
34
star
27

Switchboard

a WebSub / PubSubHubbub 0.4 hub
PHP
33
star
28

ssh-config-aws

Helper scripts to generate an ~/.ssh/config file automatically from one or more AWS accounts
Ruby
31
star
29

micropub.rocks

Micropub test suite and debugging utility
PHP
31
star
30

Telegraph

Telegraph is an API for sending Webmentions
CSS
31
star
31

TikTokBot

TikTokBot is a bot framework for Slack and IRC.
Ruby
28
star
32

Flickr-Archiver-Ruby

Backs up your entire Flickr stream to a local site.
Ruby
27
star
33

Swarm-Checkins-Import

Import your Foursquare/Swarm checkins to your Micropub-enabled website
PHP
26
star
34

Atlas

🌎 Atlas is a set of APIs for looking up information about locations
CSS
25
star
35

Auto-AirBnB-Entry

Sets the door code to the last 4 digits of the next guest's phone number before they arrive.
PHP
25
star
36

websub.rocks

Test suite and debug utilities for W3C WebSub
PHP
24
star
37

checks

print your own checks!
PHP
23
star
38

rating-stars

⭐️⭐️⭐️⭐️⭐️ A 5-star rating widget implemented in JS and CSS
HTML
22
star
39

spiderpig

πŸ•·πŸ· reduces a dynamic website into a pile of smoldering html
JavaScript
21
star
40

OwnYourSwarm

JavaScript
21
star
41

webmention.rocks

a webmention validator and test suite
PHP
20
star
42

command-line-oauth

A quick demo of doing OAuth from the command line
PHP
19
star
43

picofeed

PHP library to parse and write RSS/Atom feeds
PHP
18
star
44

QuartzDB

A flat-file database optimized to hold time-series data.
PHP
18
star
45

twitter-slack-stream

Stream tweets from conference attendees to a Slack channel
Ruby
16
star
46

youtube-chat-map

Show your livestream viewers on a map!
PHP
15
star
47

p3k-http

A simple HTTP client, used by https://p3k.io projects
PHP
13
star
48

p3k

This is a repository for filing issues against the software the runs my website. The source code is not public, but various components are.
13
star
49

p3k-micropub

Utilities to help handle Micropub requests when building servers and clients
PHP
12
star
50

indieauth.rocks

IndieAuth test suite - in progress
CSS
12
star
51

oauth-v2-1

OAuth 2.1
Shell
11
star
52

Teacup

β˜•οΈ Teacup is a simple Micropub app for tracking what you eat and drink
JavaScript
11
star
53

Flickr-Archivr

Download and archive your entire Flickr account as a static website
PHP
11
star
54

m5-core2-atem-controller

An ATEM controller using an M5 Core2
C++
11
star
55

Local-MediaWiki-Sync

Downloads all pages from a MediaWiki install to local text files.
PHP
11
star
56

chrome-open-tabs

Track your open Chrome tabs
JavaScript
10
star
57

clone-media-fragment

Clone the Media Fragment from the page's URL to any embedded media on the page
JavaScript
10
star
58

aperture-wordpress

A WordPress plugin to use Aperture as your Microsub endpoint
PHP
9
star
59

p3k-utils

a collection of smaller helper functions used by many of my applications
PHP
8
star
60

Squash-Reports

JavaScript
8
star
61

Geoloqi-Emergency-Beacon-Map

This application is a resource for citizens, medical teams and governments before, during and after disasters.
PHP
8
star
62

live-chat-overlay-remote

The remote window for the Live Chat Overlay browser extension
JavaScript
7
star
63

squawk-chat

A simple website chat widget backed by IRC
JavaScript
7
star
64

xmlrpc-micropub-bridge

XML-RPC to Micropub Bridge
PHP
7
star
65

p3k-websub

A library for subscribing to and publishing WebSub feeds
PHP
7
star
66

IndieAuth-Token-Endpoint

PHP
7
star
67

Meme-API

An API and TikTokBot integration that implements a !meme command to generate a meme image
Ruby
7
star
68

Loqi

Loqi is a friendly IRC bot
6
star
69

p3k-html-sanitizer

PHP
6
star
70

ca3db-ruby

Content-Addressable Avatar Archive
Ruby
6
star
71

Maniac-Clock

A sticky clock that also takes screenshots
JavaScript
6
star
72

Caterpillar

πŸ› Caterpillar is a PHP job queueing system based on beanstalkd
PHP
6
star
73

Teacup-Offline

Offline-first app for tracking food and drink posts
HTML
6
star
74

oauth-browser-based-apps

Best practices for OAuth in Browser-Based Apps
HTML
5
star
75

omniauth-indieauth

IndieAuth strategy for OmniAuth
Ruby
5
star
76

IndieWeb-Development

Makefile
5
star
77

Twitter-Archive-to-CSV

Convert your Twitter archive to a CSV file
PHP
5
star
78

esp-badge

esp32 with e-paper display
C++
5
star
79

music-map

Mapping all the songs we listened to on a road trip!
JavaScript
5
star
80

microsub.rocks

PHP
4
star
81

MediaWiki-Changelog-Graphs

Adds a special page showing a chart of wiki edits broken down by day, hour and month
4
star
82

PushupCounter-iOS

A silly app that counts pushups when you touch your nose to your phone
Objective-C
4
star
83

p3k-timezone

Look up the timezone given a latitude and longitude
PHP
4
star
84

BarBot

🍸
C++
4
star
85

curly

curly: A wrapper for `curl` which pretty-prints JSON output
Ruby
4
star
86

php-multipart-encoder

Multipart encoder for PHP
PHP
4
star
87

twtr

Algorithmic Twitter URL shortener
CSS
4
star
88

Gramophone

a Micropub client for publishing podcasts
PHP
4
star
89

blade-markdown-directive

adds a `@markdown` Blade directive for use in Laravel views
PHP
3
star
90

MediaWiki-Github-Issues

Render a list of Github issues in a wiki page
3
star
91

gnap-client-php

Sample GNAP client in PHP
PHP
3
star
92

reserved-usernames-php

A list of reserved usernames to prevent url collision with resource paths. Packaged as a Composer library. Source data: https://github.com/shouldbee/reserved-usernames
PHP
3
star
93

Crosswalk-Photo-Booth

Shell
2
star
94

automatic-indieauth-example

PHP
2
star
95

tz_world

A GeoJSON file of the TZ timezones of the world
Shell
2
star
96

discourse-disqus-oauth

Log in to Discourse with your Disqus account
Ruby
2
star
97

Airplane-Time

stretch time while flying between timezones - a progressive web app
HTML
2
star
98

IndieAuth-Client

Sample client app to authenticate against IndieAuth-enabled domains
PHP
2
star
99

ChatterCast-Seattle

Receive real-time 911 alerts from Seattle's open data feed. Works with Geoloqi.
PHP
2
star
100

example-indieauth-server

a prototype IndieAuth server to demonstrate what is required to build an IndieAuth server
PHP
2
star