refactor to allow for channel-level callbacks