Pass message IDs to cleanup hooks in batches
This branch refactors the cleanup hook interface to accept message IDs in batches rather than one at a time, so that expensive operations like recalculating the group count can be batched.
The return value is removed from the hook, as we can safely stop the message's cleanup timer regardless of whether the hook deletes it.
Part of #1833 (closed). Should be merged before !1382 (merged), which has been rebased on top of this branch.