signal-export


Namesignal-export JSON
Version 2.2.2 PyPI version JSON
download
home_pagehttps://github.com/carderne/signal-export
SummaryExport Signal conversations to Markdown and HTML
upload_time2024-03-27 09:17:51
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseBSD 3-Clause License
keywords backup chat export
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # signal-export
[![cicd](https://github.com/carderne/signal-export/actions/workflows/cicd.yml/badge.svg)](https://github.com/carderne/signal-export/actions/workflows/cicd.yml)
[![PyPI version](https://badge.fury.io/py/signal-export.svg)](https://pypi.org/project/signal-export/)

Export chats from the [Signal](https://www.signal.org/) [Desktop app](https://www.signal.org/download/) to Markdown and HTML files with attachments. Each chat is exported as an individual .md/.html file and the attachments for each are stored in a separate folder. Attachments are linked from the Markdown files and displayed in the HTML (pictures, videos, voice notes).

Currently this seems to be the only way to get chat history out of Signal!

Adapted from [mattsta/signal-backup](https://github.com/mattsta/signal-backup), which I suspect will be hard to get working now.

## Example
An export for a group conversation looks as follows:
```markdown
[2019-05-29, 15:04] Me: How is everyone?
[2019-05-29, 15:10] Aya: We're great!
[2019-05-29, 15:20] Jim: I'm not.
```

Images are attached inline with `![name](path)` while other attachments (voice notes, videos, documents) are included as links like `[name](path)` so a click will take you to the file.

This is converted to HTML at the end so it can be opened with any web browser. The stylesheet `.css` is still very basic but I'll get to it sooner or later.

## 🚀 Installation with Docker
This tool has some pretty difficult dependencies, so it's easier to get some help from Docker.
For most people this will probably be the easiest way.
It requires installing Docker and then pulling a [200MB image](https://hub.docker.com/r/carderne/sigexport), so avoid this if data use is a concern.

First off, [install Docker](https://docs.docker.com/get-docker/) (including following the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/) for managing Docker as a non-root user).  
And make sure you have Python installed.

Then install this package:
```bash
pip install signal-export
```

Then run the script!
It will do some Docker stuff under the hood to get your data out of the encrypted database.
```bash
sigexport ~/signal-chats
# output will be saved to the supplied directory
```

**NB** On Windows/PowerShell, you may get an error like `term 'sigexport' is not recognized`, in which case you can use the following:
```bash
python -m sigexport.main ~/signal-chats
```

## Usage
Please fully exit your Signal app before proceeding, otherwise you will likely encounter an `I/O disk` error, due to the message database being made read-only, as it was being accessed by the app.

See the full help info:
```bash
sigexport --help
```

Disable pagination on HTML, and overwrite anything at the destination:
```bash
sigexport --paginate=0 --overwrite ~/signal-chats
```

List available chats and exit:
```bash
sigexport --list-chats
```

Export only the selected chats:
```bash
sigexport --chats=Jim,Aya ~/signal-chats
```

You can add `--source /path/to/source/dir/` if the script doesn't manage to find the Signal config location.
Default locations per OS are below.
The directory should contain a folder called `sql` with `db.sqlite` inside it.
- Linux: `~/.config/Signal/`
- macOS: `~/Library/Application Support/Signal/`
- Windows: `~/AppData/Roaming/Signal/`

You can also use `--old /previously/exported/dir/` to merge the new export with a previous one.
_Nothing will be overwritten!_
It will put the combined results in whatever output directory you specified and leave your previos export untouched.
Exercise is left to the reader to verify that all went well before deleting the previous one.

## 🗻 No-Python install
I don't recommend this, and you will have issues with file-ownership and other stuff.
You can also run the Docker image directly, it just requires copy-pasting a much-longer command and being careful with volume mounts.

First set the appropriate environment variables for your OS:
```bash
# Only enter one of these!
SIGNAL_INPUT="$HOME/.config/Signal"                             # Linux
SIGNAL_INPUT="$HOME/snap/signal-desktop/current/.config/Signal" # Snap
SIGNAL_INPUT="$HOME/Library/Application Support/Signal"         # macOS
SIGNAL_INPUT="$HOME/AppData/Roaming/Signal"                     # Powershell

# And your output location (must be an absolute path)
SIGNAL_OUTPUT="$HOME/Downloads/signal-output"
```

Then run the below command, which pulls in the environment variables you set above.
```bash
# Note that the --overwrite flag is necessary when running like this
# careful where you point it!
docker run --rm \
  --net none \
  -v "$SIGNAL_INPUT:/Signal:ro" \
  -v "$SIGNAL_OUTPUT:/output" \
    carderne/sigexport:latest \
    --overwrite /output \         # this line is obligatory!
    --chats Jim                   # this line isn't
```

## 🗻 BYOD (Build-Your-Own-Docker) image
Running this script using the methods above requires you to trust that I haven't snuck anything into the Docker image.
You can inspect the code in this repo, and after `pip install`ing, you can confirm that the code installed on your computer matches this repo.
But the methods above rely on the [Docker image](https://hub.docker.com/r/carderne/sigexport), which is a bit more complex.

You can check the [Dockerfile](./Dockerfile) in this repo, and the [GitHub Actions workflow](./.github/workflows/cicd.yaml).
You can check that the last [Actions run](https://github.com/carderne/signal-export/actions) matches the time on the last push to the DockerHub registry.
But you can't guarantee that I didn't sneak something in, so the next thing is to check the image itself.

So you can run `docker inspect carderne/sigexport` and check the `Entrypoint` and `Cmd` values.
Then you can run `docker run --rm -it --entrypoint='' carderne/sigexport bash` and check what Entrypoint/Cmd values correspond to inside the container, and check that _that_ matches the repo!

You can also just build your own Docker image from this repo:
```bash
git clone https://github.com/carderne/signal-export.git
cd signal-export
docker build -t yourname/sigexport .
```

And _then_ run the Python script, but tell it to use the image you just created:
```bash
sigexport --docker-image yourname/sigexport outputdir/
```

## 🌋 No-Docker install
This is hard mode, and involves installing more stuff.
Probably easy on macOS, slightly involved on Linux, and impossible on Windows.

Before you can install `signal-export`, you need to get `sqlcipher` working.
Follow the instructions for your OS:

### Ubuntu (other distros can adapt to their package manager)
Install the required libraries.
```bash
sudo apt install libsqlite3-dev tclsh libssl-dev
```

Then clone [sqlcipher](https://github.com/sqlcipher/sqlcipher) and install it:
```bash
git clone https://github.com/sqlcipher/sqlcipher.git
cd sqlcipher
./configure --enable-tempstore=yes CFLAGS="-DSQLITE_HAS_CODEC" LDFLAGS="-lcrypto -lsqlite3"
make && sudo make install
```

### macOS
1. Install [Homebrew](https://brew.sh).
2. Run `brew install openssl sqlcipher`
3. Export some needed env vars:
```bash
export C_INCLUDE_PATH="$(brew --prefix sqlcipher)/include"
export LIBRARy_PATH="${brew --prefix sqlcipher)/lib"
```

### Windows
Ubuntu on WSL2 should work!
That is, install WSL2 and Ubuntu on Windows, and then follow the **For Linux** instructions and feel your way forward.
But probably just give up here and use the Docker method instead.

### Install signal-export
Then you're ready to install signal-export:
(Note the `[sql]` that has been added!)
```bash
pip install 'signal-export[sql]'
```

Then you should be able to use the [Usage instructions](#usage) as above.

## Uninstall
```bash
docker system prune
pip uninstall signal-export
```

## Development
```bash
git clone https://github.com/carderne/signal-export.git
cd signal-export
rye sync --no-lock
```

Various dev commands:
```bash
rye fmt         # format
rye lint        # lint
rye run check   # typecheck
rye run test    # test
rye run sig     # run signal-export
```

## Similar things
- [signal-backup-decode](https://github.com/pajowu/signal-backup-decode) might be easier if you use Android!
- [signal2html](https://github.com/GjjvdBurg/signal2html) also Android only

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/carderne/signal-export",
    "name": "signal-export",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "backup chat export",
    "author": null,
    "author_email": "Chris Arderne <chris@rdrn.me>",
    "download_url": "https://files.pythonhosted.org/packages/f0/aa/c2caef579d5443e9409cea55992012483c2d2c66ffd94f8b3e326527cf4f/signal_export-2.2.2.tar.gz",
    "platform": null,
    "description": "# signal-export\n[![cicd](https://github.com/carderne/signal-export/actions/workflows/cicd.yml/badge.svg)](https://github.com/carderne/signal-export/actions/workflows/cicd.yml)\n[![PyPI version](https://badge.fury.io/py/signal-export.svg)](https://pypi.org/project/signal-export/)\n\nExport chats from the [Signal](https://www.signal.org/) [Desktop app](https://www.signal.org/download/) to Markdown and HTML files with attachments. Each chat is exported as an individual .md/.html file and the attachments for each are stored in a separate folder. Attachments are linked from the Markdown files and displayed in the HTML (pictures, videos, voice notes).\n\nCurrently this seems to be the only way to get chat history out of Signal!\n\nAdapted from [mattsta/signal-backup](https://github.com/mattsta/signal-backup), which I suspect will be hard to get working now.\n\n## Example\nAn export for a group conversation looks as follows:\n```markdown\n[2019-05-29, 15:04] Me: How is everyone?\n[2019-05-29, 15:10] Aya: We're great!\n[2019-05-29, 15:20] Jim: I'm not.\n```\n\nImages are attached inline with `![name](path)` while other attachments (voice notes, videos, documents) are included as links like `[name](path)` so a click will take you to the file.\n\nThis is converted to HTML at the end so it can be opened with any web browser. The stylesheet `.css` is still very basic but I'll get to it sooner or later.\n\n## \ud83d\ude80 Installation with Docker\nThis tool has some pretty difficult dependencies, so it's easier to get some help from Docker.\nFor most people this will probably be the easiest way.\nIt requires installing Docker and then pulling a [200MB image](https://hub.docker.com/r/carderne/sigexport), so avoid this if data use is a concern.\n\nFirst off, [install Docker](https://docs.docker.com/get-docker/) (including following the [post-installation steps](https://docs.docker.com/engine/install/linux-postinstall/) for managing Docker as a non-root user).  \nAnd make sure you have Python installed.\n\nThen install this package:\n```bash\npip install signal-export\n```\n\nThen run the script!\nIt will do some Docker stuff under the hood to get your data out of the encrypted database.\n```bash\nsigexport ~/signal-chats\n# output will be saved to the supplied directory\n```\n\n**NB** On Windows/PowerShell, you may get an error like `term 'sigexport' is not recognized`, in which case you can use the following:\n```bash\npython -m sigexport.main ~/signal-chats\n```\n\n## Usage\nPlease fully exit your Signal app before proceeding, otherwise you will likely encounter an `I/O disk` error, due to the message database being made read-only, as it was being accessed by the app.\n\nSee the full help info:\n```bash\nsigexport --help\n```\n\nDisable pagination on HTML, and overwrite anything at the destination:\n```bash\nsigexport --paginate=0 --overwrite ~/signal-chats\n```\n\nList available chats and exit:\n```bash\nsigexport --list-chats\n```\n\nExport only the selected chats:\n```bash\nsigexport --chats=Jim,Aya ~/signal-chats\n```\n\nYou can add `--source /path/to/source/dir/` if the script doesn't manage to find the Signal config location.\nDefault locations per OS are below.\nThe directory should contain a folder called `sql` with `db.sqlite` inside it.\n- Linux: `~/.config/Signal/`\n- macOS: `~/Library/Application Support/Signal/`\n- Windows: `~/AppData/Roaming/Signal/`\n\nYou can also use `--old /previously/exported/dir/` to merge the new export with a previous one.\n_Nothing will be overwritten!_\nIt will put the combined results in whatever output directory you specified and leave your previos export untouched.\nExercise is left to the reader to verify that all went well before deleting the previous one.\n\n## \ud83d\uddfb No-Python install\nI don't recommend this, and you will have issues with file-ownership and other stuff.\nYou can also run the Docker image directly, it just requires copy-pasting a much-longer command and being careful with volume mounts.\n\nFirst set the appropriate environment variables for your OS:\n```bash\n# Only enter one of these!\nSIGNAL_INPUT=\"$HOME/.config/Signal\"                             # Linux\nSIGNAL_INPUT=\"$HOME/snap/signal-desktop/current/.config/Signal\" # Snap\nSIGNAL_INPUT=\"$HOME/Library/Application Support/Signal\"         # macOS\nSIGNAL_INPUT=\"$HOME/AppData/Roaming/Signal\"                     # Powershell\n\n# And your output location (must be an absolute path)\nSIGNAL_OUTPUT=\"$HOME/Downloads/signal-output\"\n```\n\nThen run the below command, which pulls in the environment variables you set above.\n```bash\n# Note that the --overwrite flag is necessary when running like this\n# careful where you point it!\ndocker run --rm \\\n  --net none \\\n  -v \"$SIGNAL_INPUT:/Signal:ro\" \\\n  -v \"$SIGNAL_OUTPUT:/output\" \\\n    carderne/sigexport:latest \\\n    --overwrite /output \\         # this line is obligatory!\n    --chats Jim                   # this line isn't\n```\n\n## \ud83d\uddfb BYOD (Build-Your-Own-Docker) image\nRunning this script using the methods above requires you to trust that I haven't snuck anything into the Docker image.\nYou can inspect the code in this repo, and after `pip install`ing, you can confirm that the code installed on your computer matches this repo.\nBut the methods above rely on the [Docker image](https://hub.docker.com/r/carderne/sigexport), which is a bit more complex.\n\nYou can check the [Dockerfile](./Dockerfile) in this repo, and the [GitHub Actions workflow](./.github/workflows/cicd.yaml).\nYou can check that the last [Actions run](https://github.com/carderne/signal-export/actions) matches the time on the last push to the DockerHub registry.\nBut you can't guarantee that I didn't sneak something in, so the next thing is to check the image itself.\n\nSo you can run `docker inspect carderne/sigexport` and check the `Entrypoint` and `Cmd` values.\nThen you can run `docker run --rm -it --entrypoint='' carderne/sigexport bash` and check what Entrypoint/Cmd values correspond to inside the container, and check that _that_ matches the repo!\n\nYou can also just build your own Docker image from this repo:\n```bash\ngit clone https://github.com/carderne/signal-export.git\ncd signal-export\ndocker build -t yourname/sigexport .\n```\n\nAnd _then_ run the Python script, but tell it to use the image you just created:\n```bash\nsigexport --docker-image yourname/sigexport outputdir/\n```\n\n## \ud83c\udf0b No-Docker install\nThis is hard mode, and involves installing more stuff.\nProbably easy on macOS, slightly involved on Linux, and impossible on Windows.\n\nBefore you can install `signal-export`, you need to get `sqlcipher` working.\nFollow the instructions for your OS:\n\n### Ubuntu (other distros can adapt to their package manager)\nInstall the required libraries.\n```bash\nsudo apt install libsqlite3-dev tclsh libssl-dev\n```\n\nThen clone [sqlcipher](https://github.com/sqlcipher/sqlcipher) and install it:\n```bash\ngit clone https://github.com/sqlcipher/sqlcipher.git\ncd sqlcipher\n./configure --enable-tempstore=yes CFLAGS=\"-DSQLITE_HAS_CODEC\" LDFLAGS=\"-lcrypto -lsqlite3\"\nmake && sudo make install\n```\n\n### macOS\n1. Install [Homebrew](https://brew.sh).\n2. Run `brew install openssl sqlcipher`\n3. Export some needed env vars:\n```bash\nexport C_INCLUDE_PATH=\"$(brew --prefix sqlcipher)/include\"\nexport LIBRARy_PATH=\"${brew --prefix sqlcipher)/lib\"\n```\n\n### Windows\nUbuntu on WSL2 should work!\nThat is, install WSL2 and Ubuntu on Windows, and then follow the **For Linux** instructions and feel your way forward.\nBut probably just give up here and use the Docker method instead.\n\n### Install signal-export\nThen you're ready to install signal-export:\n(Note the `[sql]` that has been added!)\n```bash\npip install 'signal-export[sql]'\n```\n\nThen you should be able to use the [Usage instructions](#usage) as above.\n\n## Uninstall\n```bash\ndocker system prune\npip uninstall signal-export\n```\n\n## Development\n```bash\ngit clone https://github.com/carderne/signal-export.git\ncd signal-export\nrye sync --no-lock\n```\n\nVarious dev commands:\n```bash\nrye fmt         # format\nrye lint        # lint\nrye run check   # typecheck\nrye run test    # test\nrye run sig     # run signal-export\n```\n\n## Similar things\n- [signal-backup-decode](https://github.com/pajowu/signal-backup-decode) might be easier if you use Android!\n- [signal2html](https://github.com/GjjvdBurg/signal2html) also Android only\n",
    "bugtrack_url": null,
    "license": "BSD 3-Clause License",
    "summary": "Export Signal conversations to Markdown and HTML",
    "version": "2.2.2",
    "project_urls": {
        "Homepage": "https://github.com/carderne/signal-export",
        "Repository": "https://github.com/carderne/signal-export"
    },
    "split_keywords": [
        "backup",
        "chat",
        "export"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e0719c1011192efe17bb9050dc94c7e59f7150285994330b3605bd2f4b32ed98",
                "md5": "6fbe8b8b1cab9aa4b96ae973b7ebbdad",
                "sha256": "34f4587746ea8d3018fbdb1b5c86c74fbcf1007dd751908d0bcca096b2f02893"
            },
            "downloads": -1,
            "filename": "signal_export-2.2.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6fbe8b8b1cab9aa4b96ae973b7ebbdad",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 19521,
            "upload_time": "2024-03-27T09:17:49",
            "upload_time_iso_8601": "2024-03-27T09:17:49.298671Z",
            "url": "https://files.pythonhosted.org/packages/e0/71/9c1011192efe17bb9050dc94c7e59f7150285994330b3605bd2f4b32ed98/signal_export-2.2.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f0aac2caef579d5443e9409cea55992012483c2d2c66ffd94f8b3e326527cf4f",
                "md5": "74f155377c56feea24aaa2f83c8ff99c",
                "sha256": "3c418936a48d465d486d4fb253ab3ddda6517c636126afdf2089b98543034c16"
            },
            "downloads": -1,
            "filename": "signal_export-2.2.2.tar.gz",
            "has_sig": false,
            "md5_digest": "74f155377c56feea24aaa2f83c8ff99c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 56944,
            "upload_time": "2024-03-27T09:17:51",
            "upload_time_iso_8601": "2024-03-27T09:17:51.937448Z",
            "url": "https://files.pythonhosted.org/packages/f0/aa/c2caef579d5443e9409cea55992012483c2d2c66ffd94f8b3e326527cf4f/signal_export-2.2.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-27 09:17:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "carderne",
    "github_project": "signal-export",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "signal-export"
}
        
Elapsed time: 0.22859s