$ cat node-template.py
Public Share
// Publishes content or files to a public URL. Supports HTML, plain text, and file downloads. Optionally protects with a PIN. The URL is deterministic — re-running the node refreshes the content without changing the link.
Output
Utility
template.py
1import json2import sys3import os4import hashlib5import string6import secrets78ALPHABET = string.digits + string.ascii_letters91011def generate_slug(workspace_id, node_id):12 # Deterministic 8-char base62 slug from workspace_id + node_id13 # NOTE: duplicated in app/services/share_storage.py — keep in sync14 h = hashlib.sha256(f"{workspace_id}:{node_id}".encode()).digest()15 num = int.from_bytes(h[:8], "big")16 slug = ""17 for _ in range(8):18 slug += ALPHABET[num % 62]19 num //= 6220 return slug212223def main():24 try:25 raw = json.loads(sys.stdin.read())26 inputs = raw.get("inputs", {})2728 content = inputs.get("content", "")29 file_input = inputs.get("file", "")30 title = inputs.get("title", "Shared Content")31 share_type = inputs.get("share_type", "html")32 pin_protected = inputs.get("pin_protected", False)33 expiry_hours = int(inputs.get("expiry_hours", 72))34 expiry_hours = max(1, min(168, expiry_hours))3536 # Validate: at least one of content or file must be provided37 has_file = bool(file_input) and os.path.isfile(f"/data/input/{file_input}")38 has_content = bool(content)39 if not has_file and not has_content:40 raise ValueError("At least one of 'content' or 'file' must be provided")4142 workspace_id = os.environ.get("WORKSPACE_ID", "")43 node_id = os.environ.get("NODE_ID", "")4445 # Compute deterministic slug46 slug = generate_slug(workspace_id, node_id) if workspace_id and node_id else ""4748 # Generate PIN if protected49 pin = None50 if pin_protected:51 pin = f"{secrets.randbelow(900000) + 100000}"5253 # Build share request54 if has_file:55 share_request = {56 "type": "file",57 "title": title,58 "source_filename": file_input,59 "slug": slug,60 "workspace_id": workspace_id or None,61 "node_id": node_id or None,62 "expiry_hours": expiry_hours,63 }64 else:65 share_request = {66 "type": share_type,67 "title": title,68 "content": str(content),69 "slug": slug,70 "workspace_id": workspace_id or None,71 "node_id": node_id or None,72 "expiry_hours": expiry_hours,73 }7475 if pin:76 share_request["pin"] = pin7778 output = {79 "share_url": "",80 "slug": slug,81 "pin": pin or "",82 "_shareRequest": share_request,83 }84 print(json.dumps(output))8586 except Exception as e:87 print(json.dumps({88 "error": str(e),89 "errorType": type(e).__name__,90 }), file=sys.stderr)91 sys.exit(1)929394if __name__ == "__main__":95 main()