Managing media on WhatsApp for Business

November 28, 2019    go golang whatsapp cron bash scripting automation devops server

If you happen to run be running a WhatsApp for Business instance, you might run into storage issues without regular maintenance like we did, recently.

A few weeks ago, outgoing messages were logging a failure to download media. From their documentation -

Media storage needs to be handled by the business. If the media volume gets full, message sending will start to fail.

Luckily, we have a fallback to textonly versions of messages for when images are not available to be downloaded for one reason or the other. A full media disk is one of them. A quick call to df -h and it was clear - outgoing and shared media had now eaten up the full 128GB of disk space we had allocated for the purpose. Before we got to the actual fix, we did quickly increase the disk space, which is pretty easy on AWS and does not require any downtime whatsoever.

The Fix

Fixing the issue was quite trivial. Incoming messages were already being dealt with from the beginning. All incoming media was copied to S3 and immediately deleted from the system. The folders we have to target for this would then be only the shared and outgoing folders that WhatsApp creates.

WhatsApp, in their documentation, states that media is stored on its servers for 14 days. So it's safe to assume that anything older than 14 days can be deleted - even though they suggest a more conservative 30 days.

I came up with a simple bash script which cron runs everyday at 10AM to clean media folders. The age of the folders is set to 14 days by default but is configurable. Open up editor and paste the code in below and save it as waprune.sh.

#!/bin/bash

[ -z "$1" ] && age=14 || age=$1 # minimum age in days, defaults to 14
fpaths=(/var/lib/docker/volumes/biz_whatsappMedia/_data/shared/* /var/lib/docker/volumes/biz_whatsappMedia/_data/outgoing/sent/*)

for i in ${fpaths[@]}; do
  echo "Going through $i"
  find $i -type d -mtime +$age -exec rm -rf {} \; > /dev/null 2>&1
done

echo "Done running script"
exit 0

The first line,
[ -z "$1" ] && age=14 || age=$1

checks for the age argument. If empty, sets it to a default of 14.

On to line 2,
fpaths=(/var/lib/docker/volumes/biz_whatsappMedia/_data/shared/* /var/lib/docker/volumes/biz_whatsappMedia/_data/outgoing/sent/*)

we declare the folders to need to go over. If you're running the default set up for WhatsApp for Business API, then these are the paths where the folders will be located. Otherwise, you can update the array to point to your custom folder paths.

Next, we loop over the folder paths,
find $i -type d -mtime +$age -exec rm -rf {} \; > /dev/null 2>&1 where, inside we find the folders that are older than the $age and promptly delete them piping the output to /dev/null for clean logs.

To setup the cronjob,

  1. Make the script an executable
    chmod +x waprune.sh
  2. Add to crontab
    crontab -e
  3. Set the cron schedule
    0 2 * * * /bin/bash /<path-to-script>/waprune.sh 30
  4. Save and exit. The configuration above sets up the script to run everyday at 2AM UTC (assuming your servers are on UTC time)


comments powered by Disqus