CREATE EXTENSION plpython3u; CREATE TABLE blockbot_config ( hostname TEXT, token TEXT ); CREATE TABLE blockbot_opt_out ( account_id BIGINT ); CREATE FUNCTION blockbot_notify( blocker TEXT, blocked TEXT, unblock BOOLEAN, hostname TEXT, token TEXT ) RETURNS boolean AS $$ import requests # non-local user, ignore if '@' in blocked: return False direction = 'unblocked' if unblock else 'blocked' r = requests.post( f'https://{hostname}/api/v1/statuses', headers={'Authorization': f'Bearer {token}'}, data={ 'status': f'@{blocked} You have been {direction} by {blocker}.', 'visibility': 'direct', } ) return r.status_code == 200 $$ LANGUAGE plpython3u; CREATE FUNCTION blockbot_trigger_inner( blocker BIGINT, blocked BIGINT, unblock BOOLEAN ) RETURNS boolean AS $$ WITH handles AS ( SELECT id, username || (CASE WHEN domain IS NULL THEN '' ELSE '@' || domain END) AS handle FROM accounts WHERE id IN ($1, $2) ) SELECT blockbot_notify( (SELECT handle FROM handles WHERE id = $1), (SELECT handle FROM handles WHERE id = $2), unblock, (SELECT hostname FROM blockbot_config), (SELECT token FROM blockbot_config) ) WHERE blocker NOT IN ( SELECT blocker FROM blockbot_opt_out WHERE account_id = $1 ); $$ LANGUAGE SQL; CREATE FUNCTION blockbot_block() RETURNS TRIGGER AS $$ BEGIN PERFORM * FROM blockbot_trigger_inner(NEW.account_id, NEW.target_account_id, false); RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER blockbot_block_trigger AFTER INSERT ON blocks FOR EACH ROW EXECUTE FUNCTION blockbot_block(); CREATE FUNCTION blockbot_unblock() RETURNS TRIGGER AS $$ BEGIN PERFORM * FROM blockbot_trigger_inner(OLD.account_id, OLD.target_account_id, true); RETURN NULL; END; $$ LANGUAGE plpgsql; CREATE TRIGGER blockbot_unblock_trigger AFTER DELETE ON blocks FOR EACH ROW EXECUTE FUNCTION blockbot_unblock();