/slack-sounds

Customize your Slack sound notifications

Primary LanguagePython

slack-sounds: Customize your Slack sound notifications

TL;DR: This is a story of how I felt nostalgic for the old Uh-Oh! ICQ sound and ended up with a quick research on how Slack stores and uses media files. Eventually I ended up developing a simple tool to customize Slack sound notifications. Please note that currently my script edits the Hummus notification sound but this can be easily changed if needed.

slack.icq.mov

Instructions (Mac OSX only for now)

  1. Change Slack’s notification sound to Hummus (we are going to edit it) Slack-->Preferences-->Notifications-->Select Hummus
  2. run python3 slack_change_sound.py sound.mp3
  3. Restart Slack

The Short Story

In essence, Slack does not allow users to customize their sound notifications as they wish but I wanted to choose my own notification sound. After a bit of research I discovered that Slack stores the sound files in multiple locations, but the most important location is a directory with cache files which have a simple yet proprietary binary structure. After a bit of playing I was able to re-create the structure of Slack cache files and I got my desired ICQ sound! I also wrote a generic tool to do this for you.

The Longer Story: The Stages of Grief

Fail #1: Denial

So, I wanted to change my Slack notification sound to the classical Uh-Oh! ICQ sound. Sounds easy. I went to Slack Preference --> Notifications but could not find how to choose my own customized sound. Intrigued, I looked online but still could not find how to do this. Looks like Slack limits the user to a few predefined sounds only.

image

OK, maybe Slack doesn't allow you to change the sound to a custom one. Let's find out where the sound files are stored on disk and just replace them manually. For example - let's try to locate Hummus.mp3 sound and just modify it. find / -name Hummus.mp3.

The Slack application is built on the Electron framework. Electron is a free and open-source software framework developed and maintained by GitHub. The framework is designed to create desktop applications using web technologies which are rendered using a flavor of the Chromium browser engine, and a backend using the Node.js runtime environment.

Fail #2: Anger

To investigate where resources are stored, I went to Slack installation directory /Applications/Slack.app and searched for resource files. I found all the resource files including Hummus.mp3 Under the ./Contents/Resources directory.

image

Bingo. I changed it to my ICQ sound, restarted Slack, and asked someone to send me a message. Nothing changed. I still hear the annoying Hummus sound.

Fail #3: Bargaining

I knew that Electron applications store resources in a proprietary archive file called .asar. So OK, maybe the resource files are extracted every single time from the .asar archive. I unpacked the app-x64.asar file using npx asar extract app-x64.asar app-x64.asar.unpacked and observed the Hummus.mp3 file within app-x64.asar.unpacked directory. Cool, I modified the file, packed back the .asar archive using npx asar pack app-x64.asar.unpacked/ app-x64.asar and restarted Slack. This time Slack did not even open.

image

Fail #4: Depression

I looked at Electron source code and found out that an integrity check was added in the form of SHA-256 hash of the .asar archive header (pure JSON structure after the first DWORD size). No problem, I wrote a simple script to calculate the hash and modified ElectronAsarIntegrity within ./Contents/Info.plist. Restarted Slack again and it still doesn't work. After a quick Google search I remembered that updated Mac OSX applications are signed, so Slack needed to be re-signed again because we modified its files. I used codesign --sign - --force --deep --preserve-metadata=entitlements /Applications/Slack.app and now I was finally able to restart Slack successfully! but the sound did not change... Still Hummus.

image

Frustrated, I checked all the open file descriptors that Slack is using lsof -n | grep -i slack but I could not find any .mp3 files. Interesting. It means that probably Slack loads this dynamically and uses it in-memory somehow.

image

Fail #5: Acceptance

At this point I determined that Slack is probably getting the sound files remotely somehow. It was strange because why would Slack request the sound files every single time from a remote server? But it was my only explanation and I decided to research this. A split second before spinning my Burp, I decided to check how the true web application behaves. I opened slack.com and entered my workspace. Went to settings and selected one of the sound files. As expected, a remote sound file resource was requested and retrieved.

Slack___Sharon_Brizinov___Claroty

I selected the same sound file again but this time no request was fired. Probably a cache... wait! Maybe something similar happens with our Slack Electron app? but instead of asking the media every time, there will be a cache which stores the last response. This will explain why all of our file modifications didn't work and why we don't see any .mp3 file loaded in lsof.

Success!

Using lsof I knew where Slack stores it's temporary data (databases, cache files, downloads, index, etc). There are two options -

  1. ~/Library/Application Support/Slack
  2. ~/Library/Containers/com.tinyspeck.slackmacgap/Data/Library/Application Support/Slack

I enter the support directory and saw multiple files and directories. One of them was Cache.

image

Inside Cache there's another directory called Cache_Data and inside thousands of files with random looking names. probably some kind of hashes and an index file pointing at them.

image

I used grep to search for part of the Hummus.mp3 content and found a match!

image

After a bit of playing with the files there I understood that _s cache files are the ones I needed. I started to explore the binary structure of these cache files and finally wrote my own Slack-cache-file builder. Here are some key elements of a Slack cache file -

_Users_sharonbrizinov_Library_Containers_com_tinyspeck_slackmacgap_Data_Library_Application_Support_Slack_Cache_Cache_Data_13f007daa736b6cb_s_-_010_Editor

Eventually I wrote a quick-and-dirty Python script which receives a path to a .mp3 sound file and edits the Hummus cache file with the customized file. Great Success.

Summary

It was a fun journey into understanding how Slack stores and uses media files. The default media files within the .asar archive are probably there just in case there will be a connectivity issue in the first time Slack is loaded. The real deal are the Slack cache files which are being used heavily by Slack across many different functions, including notification sounds :)