Approve/Reject buttons in Slack, end to end. Slack posts its interactivity payload as JSON inside a urlencoded payload FORM FIELD, so it must be parsed with yaml_to_json before anything can read it, and the signature is over the RAW body. Records the decision, then replaces the original message via response_url so the buttons disappear. Catches chat.postMessage failing as ok:false at HTTP 200, and a double-click is idempotent rather than an error.