Package: imessage-conversation-analyzer
iMessage Conversation AnalyzerCopyright 2020-2024 Caleb EvansReleased under the MIT licenseiMessage Conversation Analyzer (ICA) is a fully-typed Python library that will
read the contents of an iMessage conversation via the Messages app's database on
macOS. You can then gather various metrics of interest on the messages. The library also includes a CLI utility for easy use.Much of this program was inspired by and built using findings fromthis blog post by Yorgos Askalidis.CaveatsPlease note that currently, you can only query conversations between you and a
single other person (i.e. group chats are currently unsupported).It should also be clarified that this program only supports macOS, since the
presence of the chat.db file in your user Library directory is essential for the
program to function.Installation1. Install Python 3To install Python 3, you'll need to install the Apple Command Line Tools, which
you can install by running:xcode-select--installDon't worry if you see a long download time; it will shorten rather quickly.2. Set up virtualenvpip3installvirtualenvvirtualenv--python=python3.virtualenvsource.virtualenv/bin/activate3. Install project depdendenciespipinstall-rrequirements.txtUsageThe package includes both a Command Line API for simplicity/convenience, as well
as a Python API for maximum flexibility.Command Line APITo use ICA from the command line, simply invoke theicacommand. The minimum required arguments are:A path to an analyzer file to run, or the name of a built-in analyzerThe first and last name of the contact, via the-c/--contactflagIf the contact has no last name on record, you can just pass the first
nameOther formatsYou can optionally pass the-f/--formatflag to output to a specific format
like CSV (supported formats includecsv,excel/xlsx, andmarkdown/md).icamessage_totals-c'Jane Fernbrook'-fcsvica./my_custom_analyzer.py-c'Jane Fernbrook'-fcsvWriting to a fileFinally, there is an optional-o/--outputflag if you want to output to a
specified file. ICA will do its best to infer the format from the file
extension, although you could also pass--formatif you have special filename
requirements.icatranscript-c'Thomas Riverstone'-o./my_transcript.xlsxBuilt-in analyzersThe library includes several built-in analyzers so that you can use ICA out of
the box:message_totals: a summary of message and reaction counts, by person and in
total, as well as other insightful metricsattachment_totals: lists count data by attachment type, including
number of Spotify links shared, YouTube videos, Apple Music, etc.most_frequent_emojis: count data for the top 10 most frequently used emojis
across the entire conversationtotals_by_day: a comprehensive breakdown of message totals for every day
you and the other person have been messaging in the conversationtranscript: a full, unedited transcript of every message, including
reactions, between you and the other person (attachment files not included)Again, to call one of these built-in analyzers, just pass it as the first
argument to theicacommand:icamost_frequent_emojis-c'Jane Fernbrook'Python APIThe Python API is much more powerful, allowing you to integrate ICA into any
type of Python project that can run on macOS. All of the built-in analyzers
themselves (under theica/analyzersdirectory) actually use this API.# get_my_transcript.pyimportpandasaspdimportica# Export a transcript of the entire conversationdefmain()->None:# Allow your program to accept all the same CLI arguments as the `ica`# command; you can skip calling this if have other means of specifying the# contact name and output formatcli_args=ica.get_cli_args()# Retrieve the dataframes corresponding to the massaged contents of the# database; dataframes include `message` and `attachment`dfs=ica.get_dataframes(contact_name=cli_args.contact_name,timezone=cli_args.timezone)# Send the results to stdout (or to file) in the given formatica.output_results(pd.DataFrame({"timestamp":dfs.messages["datetime"],"is_from_me":dfs.messages["is_from_me"],"is_reaction":dfs.messages["is_reaction"],# U+FFFC is the object replacement character, which appears as# the textual message for every attachment"message":dfs.messages["text"].replace(r"\ufffc","(attachment)",regex=True),}),# The default format (None) corresponds to the pandas default dataframe# table formatformat=cli_args.format,# When output is None (the default), ICA will print to stdoutoutput=cli_args.output,)if__name__=="__main__":main()You can run the above program using theicacommand, or execute it directly
like any other Python program.ica./get_my_transcript.py-c'Thomas Riverstone'python./get_my_transcript.py-c'Thomas Riverstone'python-mget_my_transcript-c'Thomas Riverstone'You're not limited to writing a command line program, though! Theica.get_dataframes()function is the only function you will need in any
analyzer program. But beyond that, feel free to import other modules, send your
results to other processes, or whatever you need to do!You can also import any built-in analyzer (for your own post-processing) via theica.analyzersnamespace.Errors and exceptionsBaseAnalyzerException: the base exception class for all library-related
errors and exceptionsContactNotFoundError: raised if the specified contact was not foundConversationNotFoundError: raised if the specified conversation was not
foundFormatNotSupportedError: raised if the specified format is not supported by
the libraryUsing a specific timezoneBy default, all dates and times are in the local timezone of the system on which
ICA is run. If you'd like to change this, you can pass the--timezone/-toption to the CLI with an IANA timezone name.icatotals_by_day-c'Daniel Brightingale'-tUTCicatotals_by_day-c'Daniel Brightingale'-tAmerica/New_YorkThe equivalent option for the Python API is thetimezoneparameter toica.get_dataframes:dfs=ica.get_dataframes(contact_name=my_contact_name,timezone='UTC')