Custom fields
A custom field is a named piece of information attached to a file: an order number, a customer, a due date, a status. Fields are set up per share, filled in by people or by Captur as documents arrive, and they’re searchable. Most useful scripts read or write them.
As in the last chapter, these examples need a share that has the fields in question, so they’re marked as not run. Each is checked to be valid MaSH.
Reading a field
Section titled “Reading a field”A file’s fields holds its fields, keyed by the field’s name:
set doc to mash.files.get("Orders", "Inbox/despatch-1182.pdf")set orderNo to doc.fields["Order No"]printline "Order number: {{orderNo}}"doc = mash.files.get("Orders", "Inbox/despatch-1182.pdf")orderNo = doc.fields["Order No"]printline("Order number: {{orderNo}}")A field with nothing in it reads as null. Add a fallback with ?? so your script never trips over a gap:
set doc to mash.files.get("Orders", "Inbox/despatch-1182.pdf")set customer to mash.str(doc.fields["Customer"] ?? "").trim().toString()if customer is "" set customer to "Unknown customer"enddoc = mash.files.get("Orders", "Inbox/despatch-1182.pdf")customer = mash.str(doc.fields["Customer"] ?? "").trim().toString()if (customer == "") { customer = "Unknown customer"}Two traps to know about:
- Asking for a field the share doesn’t have. Check with
doc.fields.has("Customer")first when the name comes from somewhere you don’t control. - Fields still being filled in. When a script runs on a new document, Captur may not have written its fields yet. Treat an empty field as “not ready”, not as an error. That’s why real scripts check for a usable value early and
returnquietly when there isn’t one yet.
To see what a file carries, doc.fields.keys() lists the field names.
Fields with several values
Section titled “Fields with several values”Some fields hold a list, such as several parties on one claim. A multi-value field reads as a collection. Join it into one line, or loop over it:
set doc to mash.files.get("Claims", "N1 Claim Form.pdf")set parties to mash.collect(doc.fields["Party"] ?? [])printline parties.join("; ")each parties as party printline "Party: {{party}}"enddoc = mash.files.get("Claims", "N1 Claim Form.pdf")parties = mash.collect(doc.fields["Party"] ?? [])printline(parties.join("; "))each (parties) as party { printline("Party: {{party}}")}Writing a field
Section titled “Writing a field”Use fields.set(name, value). It checks the field exists on the share, converts the value to the field’s type (text, number, boolean, date), records the change in the activity log, and respects field permissions:
set doc to mash.files.get("Orders", "Inbox/despatch-1182.pdf")doc.fields.set("Status", "Ordered")doc.fields.set("Order No", "SO-20417")doc = mash.files.get("Orders", "Inbox/despatch-1182.pdf")doc.fields.set("Status", "Ordered")doc.fields.set("Order No", "SO-20417")For a multi-value field, set replaces the whole list by default. Add or remove single values with the action option:
set doc to mash.files.get("Claims", "N1 Claim Form.pdf")doc.fields.set("Party", "Acme Ltd", {action: "add"})doc.fields.set("Party", "Beta Ltd", {action: "remove"})doc = mash.files.get("Claims", "N1 Claim Form.pdf")doc.fields.set("Party", "Acme Ltd", {action: "add"})doc.fields.set("Party", "Beta Ltd", {action: "remove"})The three actions are add, remove and replace (the default).
Setting a field that isn’t configured on the share is an error. If you aren’t sure, check has first.
Finding files by field
Section titled “Finding files by field”mash.fields.findFiles takes a dictionary of field names and values. It returns the files where every one matches, across all the shares the script’s owner can read:
set filters to {}set filters["Order No"] to "SO-20417"
set related to mash.fields.findFiles(filters)printline "{{count(related)}} documents belong to this order"filters = {}filters["Order No"] = "SO-20417"
related = mash.fields.findFiles(filters)printline("{{count(related)}} documents belong to this order")Each result is a dictionary with name, path and share_id, so you can fetch the full file:
set filters to {}set filters["Order No"] to "SO-20417"
each mash.fields.findFiles(filters) as hit set file to mash.files.get(hit["share_id"], hit["path"]) printline "{{file.name}} on {{file.share.name}}"endfilters = {}filters["Order No"] = "SO-20417"
each (mash.fields.findFiles(filters)) as hit { file = mash.files.get(hit["share_id"], hit["path"]) printline("{{file.name}} on {{file.share.name}}")}A script is only ever allowed to find what its owner may read. An automation owned by a user searches that user’s shares. An automation owned by an admin searches every share.
Try it
Section titled “Try it”Pick a field on a test share, such as a status. Write a script that finds every file where it’s "Review" and prints each name.
Next, you’ll make a script run by itself when something happens.