client.rules
هر متد در این فضای نام: امضا، پارامترها، آنچه برمیگرداند و یک نمونه.
متدها
Conditions and actions evaluated on arriving mail, with dry runs and an audit trail.
rules.list
List mail rules in evaluation order
list(enabled: nil, limit: nil, cursor: nil, api_key: nil) -> OpenEmail::PageReturns one page of the mailbox's rules in the order they run on arriving mail: ascending position, then createdAt, then id. This is deliberately not newest first. With stopProcessing in play, the same rules in a different order file mail differently, so the order you read is the order that matters.
Paging is keyset on that same (position, createdAt, id) tuple, and the cursor is opaque: it holds where the last rule on the page sat in that order. Pass next_cursor back as cursor: while has_more? is true, or let list_all or iterate walk the pages. enabled: narrows to enabled or disabled rules, and the SDK sends it as the literal word true or false.
پارامترها
enabledBooleanRestricts the page to enabled (
true) or disabled (false) rules. Omit it for both.limitIntegerRows per page, a whole number from 1 to 100. The server defaults to 25.
cursorStringThe
next_cursorfrom the previous page. Never build one yourself.api_keyStringOverrides the client API key for this call only.
خروجی
An OpenEmail::Page of rule Hashes, with items, has_more? and next_cursor. Each rule has id, name, description, enabled, position, match, conditions, actions, stopProcessing, lastMatchedAt, matchCount, createdAt and updatedAt.
نمونه
page = client.rules.list(enabled: true, limit: 100) page.items.each do |rule| puts "#{rule[:position]} #{rule[:name]} #{rule[:matchCount]} #{rule[:stopProcessing]}"endنکتهها
A rule deleted, moved or renamed between pages never breaks the walk: the next page starts at the first rule that sorts after the cursor. A cursor this list did not hand out is a 400
invalid_cursor.A key limited to particular addresses or domains lists only the rules that can act on mail delivered to them: every rule without a
delivered_tocondition, and a rule with one when it can match an address the key holds.A mailbox holds at most 100 rules, so
limit: 100always returns them in a single page.A
matchCountstill at zero after weeks is the cheap sign that a rule's conditions never hold.list_runshas the detail.
همچنین در دسترس در
- API
GET /rules- TypeScript
rules.list()- Python
rules.list()- CLI
openemail rules list
rules.list_all
Collect every rule into one array
list_all(enabled: nil, limit: nil, cursor: nil, api_key: nil) -> Array<Hash>Walks every page of the rule list and returns all rules in evaluation order, which is the order to read them in when reasoning about what happens to a message. A mailbox holds at most 100 rules, so passing limit: 100 fetches them in a single request, while the server default of 25 takes up to four.
enabled: collects only enabled or only disabled rules. A disabled rule keeps its position, so a filtered Array hides rules that still sit between the ones you see, and reorder needs every id. Collect without the filter whenever you intend to change the order.
پارامترها
enabledBooleanCollects only enabled (
true) or disabled (false) rules.limitIntegerPage size for each request, 1 to 100. The server defaults to 25.
cursorStringStarts the walk from this cursor instead of the first page.
api_keyStringOverrides the client API key for every page of this walk.
خروجی
An Array of rule Hashes holding every matching rule, sorted by position, then createdAt, then id.
نمونه
rules = client.rules.list_all(limit: 100) stoppers = rules.select { |rule| rule[:enabled] && rule[:stopProcessing] } p stoppers.map { |rule| "#{rule[:position]}: #{rule[:name]}" }نکتهها
If any page fails the call raises, and the rules already fetched are discarded.
Positions are not contiguous. Deleting a rule leaves a gap, and
updatewithpositioncan make two rules share a number.
همچنین در دسترس در
- API
GET /rules- TypeScript
rules.listAll()- Python
rules.list_all()
rules.iterate
Stream rules one at a time in evaluation order
iterate(enabled: nil, limit: nil, cursor: nil, api_key: nil, &block) -> Enumerator<Hash>Returns an Enumerator that yields rules in the order arriving mail meets them, or yields each one to a block when given one, and fetches the next page only when the current one is drained. Without a block nothing is requested until you consume it, and breaking out of the loop stops further requests.
The walk ends when has_more? is false, when a page carries no next_cursor, or when the server repeats a cursor. The cursor points into the (position, createdAt, id) order, so moving rules while you iterate can skip or repeat some of them. Finish reading before you call reorder or update with a position.
پارامترها
enabledBooleanYields only enabled (
true) or disabled (false) rules.limitIntegerPage size per request, 1 to 100. The server defaults to 25.
cursorStringStarts the walk from this cursor instead of the first page.
api_keyStringOverrides the client API key for every page of this walk.
خروجی
An Enumerator of rule Hashes (or yields each one to a block), one rule per step.
نمونه
client.rules.iterate(enabled: true) do |rule| next unless rule[:stopProcessing] puts "Mail matching \"#{rule[:name]}\" skips every rule after position #{rule[:position]}" breakendنکتهها
A page request that fails raises out of the loop, after every rule of the pages before it has been yielded.
همچنین در دسترس در
- API
GET /rules- TypeScript
rules.iterate()- Python
rules.iterate()
rules.get
Read one mail rule
get(id, api_key: nil) -> HashFetches a single rule by its rul_ id. Rules have no slug and the name is editable, so store the id if your code needs to find the rule again.
The stored conditions are normalised, so negate is always present and false unless you set it. lastMatchedAt and matchCount move each time the rule fires on an arriving message, which makes them the quickest way to see whether a rule is doing anything without reading list_runs.
پارامترها
idStringالزامیThe rule's
rul_id.api_keyStringOverrides the client API key for this call only.
خروجی
A Hash with id, name, description, enabled, position, match, conditions, actions, stopProcessing, lastMatchedAt, matchCount, createdAt and updatedAt.
نمونه
rule = client.rules.get("rul_4f1c9a2b7d3e8f6a0b5c1d2e") p rule[:enabled], rule[:match], rule[:conditions].lengthp rule[:matchCount], rule[:lastMatchedAt]نکتهها
A missing rule is a 404
resource_not_found, whether it was deleted or belongs to another workspace. A key limited to particular addresses or domains gets the same 404 for a rule that cannot act on mail delivered to them.matchCountcounts messages the rule matched, not actions it carried out. A match whose actions were all refused still counts.
همچنین در دسترس در
- API
GET /rules/{id}- TypeScript
rules.get()- Python
rules.get()- CLI
openemail rules get
rules.create
Create a mail rule at the end of the order
create(body = nil, api_key: nil, **fields) -> HashCreates a rule that runs on mail arriving in the mailbox, with no API call involved once it exists. It is appended after every existing rule and is enabled unless you pass enabled: false. There is no position on create: move the rule afterwards with reorder, the only call that guarantees an exact sequence. Creating it disabled and calling test first is the safe order.
Conditions are a flat list. match: "all" is AND, match: "any" is OR, and negate: true inverts a single condition, so (A and B) or C takes two rules. value is always a String. has_attachment and spam take only equals with "true" or "false". attachment_size, message_size, hour and weekday take a number with gt, lt or equals, and gt or lt on any other field is refused. Text comparisons ignore case, and matches is a whole value glob over * and ? that needs at least two letters or digits. A header condition must name the header it reads in header.
Actions apply in order. label and remove_label take a label id, forward takes an email address and reply takes a template id or slug. A forward is only delivered once the destination has confirmed it accepts mail forwarded from your domain, and a reply goes to each sender at most once per 24 hours and never to bounces, auto-responders or mailing lists. A rule with reject must also test envelope_from, otherwise it is a 422 reject_needs_envelope, because refusing mail on the strength of a From header bounces the mailing list rather than the author.
پارامترها
nameStringالزامیDisplay name, 1 to 100 characters after trimming and unique per mailbox.
descriptionStringFree text note, at most 500 characters, or nil.
enabledBooleanWhether the rule runs on arriving mail. Defaults to true.
matchStringWhether every condition (
all) or any single one (any) must hold. Defaults toall.conditionsArray<Hash>الزامی1 to 20 conditions, each a Hash with
field,opandvalue, plus an optionalheader(at most 128 characters) andnegate.valueis at most 512 characters.actionsArray<Hash>الزامی1 to 10 actions, each a Hash with
typeandvalue, withvalueat most 320 characters.stopProcessingBooleanWhen true, no later rule runs on a message this rule matched. Defaults to false.
api_keyStringOverrides the client API key for this call only.
خروجی
A Hash for the new rule, shaped like the one get returns, with the new id, the position it was appended at, matchCount of 0 and lastMatchedAt of nil.
نمونه
label_ids = client.labels.list_all.to_h { |label| [label[:name], label[:id]] } rule = client.rules.create( name: "Receipts to their own label", enabled: false, conditions: [ {field: "from_domain", op: "equals", value: "stripe.com"}, {field: "subject", op: "contains", value: "receipt"} ], actions: [ {type: "label", value: label_ids["Receipts"]}, {type: "archive"} ], stopProcessing: true) puts rule[:id], rule[:position]نکتهها
Validation failures are a 422
invalid_rulewhoseparamnames the path, such asconditions.0.op. A duplicate name is a 409rule_name_taken.A mailbox holds at most 100 rules, and the next create is a 422
rule_limit_reached.from_domainalso matches subdomains, soequalswithstripe.comholds for mail frommail.stripe.com.hourandweekdayare read in UTC, withweekday0 for Sunday.Not retried by the SDK and there is no idempotency key, so repeating a create after a lost response makes a second rule unless the name collides.
A key limited to particular addresses or domains creates only a rule that acts on nothing but mail delivered to them, so it needs a
delivered_tocondition no other address in the workspace matches, such asequalswith one of its addresses. Anything else is a 422capability_unsupportedonconditions.
همچنین در دسترس در
- API
POST /rules- TypeScript
rules.create()- Python
rules.create()- CLI
openemail rules create
rules.update
Change a rule, replacing conditions or actions whole
update(id, patch = nil, api_key: nil, **fields) -> HashMerges the patch onto the stored rule and validates the whole result, so an omitted field keeps its stored value instead of collecting a default. A patch that only renames a rule cannot switch a disabled one back on, and a patch that adds a reject action is checked against the conditions already stored.
conditions and actions replace the entire Array. There is no way to add or remove a single element: read the rule, change the Array, and send all of it. match and stopProcessing read across the whole set, which is why element level edits are not offered.
position moves this one rule without renumbering the others. Positions are not unique and ties break by createdAt then id, so landing on an occupied position puts the older rule first. Use reorder when the exact sequence matters. Setting enabled: false is the reversible alternative to delete, and a disabled rule keeps its place in the order.
پارامترها
idStringالزامیThe rule's
rul_id.nameStringReplacement name, 1 to 100 characters and unique per mailbox.
descriptionStringReplacement note of at most 500 characters, or nil to clear it.
enabledBooleanTurns the rule on or off without moving it.
matchStringWhether every condition (
all) or any single one (any) must hold.conditionsArray<Hash>Complete replacement list of 1 to 20 conditions.
actionsArray<Hash>Complete replacement list of 1 to 10 actions.
stopProcessingBooleanWhen true, no later rule runs on a message this rule matched.
positionIntegerNew position, a whole number from 0 to 1,000,000. Other rules keep theirs.
api_keyStringOverrides the client API key for this call only.
خروجی
The rule Hash as saved, shaped like the one get returns, with a fresh updatedAt. matchCount and lastMatchedAt are untouched by an edit.
نمونه
rule = client.rules.get("rul_4f1c9a2b7d3e8f6a0b5c1d2e") updated = client.rules.update( rule[:id], conditions: [*rule[:conditions], {field: "has_attachment", op: "equals", value: "true"}], enabled: true) p updated[:conditions].length, updated[:enabled]نکتهها
Validation failures are a 422
invalid_ruleorreject_needs_envelopewithparamnaming the path, such asconditions.1.value.Renaming onto another rule's name is a 409
rule_name_taken.Not retried by the SDK, since there is no idempotency key on this resource.
A key limited to particular addresses or domains may patch only a rule that acts on nothing but mail delivered to them, and the patched rule has to stay that way. Anything else is a 422
capability_unsupported, and a rule the key cannot list is a 404.
همچنین در دسترس در
- API
PATCH /rules/{id}- TypeScript
rules.update()- Python
rules.update()- CLI
openemail rules update
rules.delete
Delete a mail rule
delete(id, api_key: nil) -> HashPermanently removes a rule. There is no undo, and mail it already filed stays where it put it. If you might want the rule back, update(id, enabled: false) switches it off and keeps its place in the order.
The run history survives. list_runs(rule_id: id) still returns what the rule did, under the name it had at the time. The other rules are not renumbered, so a gap in position is normal afterwards.
پارامترها
idStringالزامیThe rule's
rul_id.api_keyStringOverrides the client API key for this call only.
خروجی
A Hash with object set to rule, id and deleted set to true.
نمونه
deleted = client.rules.delete("rul_4f1c9a2b7d3e8f6a0b5c1d2e") puts deleted[:id], deleted[:deleted]نکتهها
Deleting frees the name, so a new rule can take it straight away.
Not retried by the SDK. Repeating a delete that already succeeded is a 404 about something that worked.
A key limited to particular addresses or domains deletes only a rule that acts on nothing but mail delivered to them. Another rule it can list is a 422
capability_unsupported, and one it cannot list is a 404.
همچنین در دسترس در
- API
DELETE /rules/{id}- TypeScript
rules.delete()- Python
rules.delete()- CLI
openemail rules delete
rules.reorder
Set the evaluation order of every rule
reorder(rule_ids, api_key: nil) -> Array<Hash>Replaces the whole order in one transaction. rule_ids must name every rule on the mailbox exactly once, and each rule's position becomes its index in the Array, starting at 0. Either the whole order lands or nothing moves.
A list that leaves a rule out or names one twice is a 422 incomplete_order, because an omitted rule would have to go somewhere and there is no right answer for where. Build the list from list_all without the enabled: filter so disabled rules are included. The new order applies to the next message that arrives, and mail already filed is not revisited.
پارامترها
rule_idsArray<String>الزامیEvery rule id on the mailbox in the order they should run, 1 to 100 entries.
api_keyStringOverrides the client API key for this call only.
خروجی
An Array of rule Hashes holding every rule on the mailbox, sorted by its new position. The SDK unwraps the list envelope, so this is a plain Array rather than an OpenEmail::Page.
نمونه
rules = client.rules.list_all(limit: 100)spam, rest = rules.partition { |rule| rule[:name] == "Refuse known spammers" } ordered = client.rules.reorder((spam + rest).map { |rule| rule[:id] }) p ordered.map { |rule| "#{rule[:position]} #{rule[:name]}" }نکتهها
An id that is not on this mailbox is a 404
resource_not_found, and nothing moves.The SDK retries this call on network errors and retryable statuses, since applying the same order twice lands in the same place.
A mailbox with no rules cannot call this: an empty
rule_idsis a 422invalid_parameter.A key limited to particular addresses or domains names every rule
listreturns for it and nothing else. It may move only the rules that act on nothing but mail delivered to its addresses, anywhere among the others; moving any other rule is a 422capability_unsupported. The rules it cannot list keep their places, and the result lists only the rules it can see.
همچنین در دسترس در
- API
POST /rules/reorder- TypeScript
rules.reorder()- Python
rules.reorder()- CLI
openemail rules reorder
rules.test
Dry run a rule against mail already in the mailbox
test(id, body = nil, api_key: nil, **fields) -> HashEvaluates one rule against stored mail with the same matcher delivery uses and reports what it would have caught and what it would do. It changes nothing, sends nothing and files nothing, which is why it needs only rules:read. It works on a disabled rule, so the intended sequence is create with enabled: false, test, then enable.
By default it reads up to 50 inbox threads from the last 30 days. For each thread it tests the newest message the mailbox received rather than sent, and threads that fail to load or hold only your own messages are skipped, so scanned can come in below limit. Pass threadIds to test specific threads from any folder instead, and days and limit are then ignored. A message an existing rule already moved out of the inbox is not in the default sample, and list_runs is the record of what really happened.
Read warnings before matched. field_unevaluable means a condition reads something stored mail no longer carries (envelope_from, header, list_id, delivered_to or message_size), so it never held here, and under negate it holds on everything. field_approximate flags attachment, hour and weekday conditions answered from stored data that can differ from delivery. body_encrypted means a body condition met mail whose body is sealed. forward_loop means a forward target leads back to this mailbox, and forward_unverified means the target is not hosted here, so the forwarded copy is rebuilt and loses its original DKIM signature.
پارامترها
idStringالزامیThe rule's
rul_id. Disabled rules can be tested.threadIdsArray<String>Up to 50 specific thread ids to test instead of the recent window. Ids that fail to load are skipped.
daysIntegerHow far back the default window reaches, 1 to 365. Defaults to 30.
limitIntegerHow many recent inbox threads to read, 1 to 200. Defaults to 50.
api_keyStringOverrides the client API key for this call only.
خروجی
A Hash with ruleId, scanned, matched, wouldApply (the actions as type or type:value), messages (each a Hash with threadId, from, subject and receivedAt) and warnings (each a Hash with code and value, where value is the field name or the forward address).
نمونه
dry = client.rules.test("rul_4f1c9a2b7d3e8f6a0b5c1d2e", days: 30, limit: 100) p dry[:scanned], dry[:matched], dry[:wouldApply]p dry[:messages].map { |message| message[:subject] } client.rules.update(dry[:ruleId], enabled: true) if dry[:warnings].empty? && dry[:matched].positive?نکتهها
There is no call that applies a rule to mail already in the mailbox. Rules only act on mail that arrives while they are enabled.
wouldApplylists what the rule declares. At delivery a forward to an unconfirmed address or a suppressed reply still fails, and onlylist_runsshows that.The SDK retries it on network errors and retryable statuses, because a dry run has no side effects.
A key limited to particular addresses or domains tests only a rule it can list, against conversations delivered to its addresses.
threadIdsnaming any other conversation are skipped, and a rule it cannot list is a 404.
همچنین در دسترس در
- API
POST /rules/{id}/test- TypeScript
rules.test()- Python
rules.test()- CLI
openemail rules test
rules.list_runs
List what rules actually did to arriving mail
list_runs(rule_id: nil, thread_id: nil, limit: nil, cursor: nil, api_key: nil) -> OpenEmail::PageReturns one page of the rule audit log, newest first. Each row is one rule matching one arriving message, with the actions that took effect and the ones that were refused.
Each row copies the rule's name at the moment it fired, so renamed and deleted rules still read correctly, and rule_id: works for a rule that no longer exists. thread_id: answers the other common question: why a particular message ended up where it did.
actions lists the action types that were applied, and failures lists refusals as type: reason. A non empty failures means the rule matched but the mailbox declined part of it, for example a reply suppressed because that sender was already answered in the last day, a forward to an address that has not confirmed, or a reject that could not be refused at SMTP and was filed as spam instead.
پارامترها
rule_idStringOnly runs of this rule, including a rule that has since been deleted.
thread_idStringOnly runs recorded against this thread.
limitIntegerRows per page, a whole number from 1 to 100. The server defaults to 25.
cursorStringThe
next_cursorfrom the previous page. Never build one yourself.api_keyStringOverrides the client API key for this call only.
خروجی
An OpenEmail::Page of run Hashes, with items, has_more? and next_cursor. Each run has id, ruleId, ruleName, threadId, messageId, sender, subject, actions, failures and createdAt.
نمونه
page = client.rules.list_runs(rule_id: "rul_4f1c9a2b7d3e8f6a0b5c1d2e", limit: 50) page.items.each do |run| puts "#{run[:createdAt]} #{run[:sender]} #{run[:actions]} #{run[:failures]}"endنکتهها
actionsholds bare types such aslabelorarchive, without the label id or address the rule was configured with. Read the rule itself for those.senderis lower-cased and trimmed, andsubjectis cut at 500 characters.A cursor naming a run that never existed is a 400
invalid_cursor.A key limited to particular addresses or domains reads only the runs of rules it can list, so runs of a rule deleted since, whose conditions are gone, are left out for such a key.
Only mail arriving while the rule is enabled writes here.
testand edits never do.
همچنین در دسترس در
- API
GET /rules/runs- TypeScript
rules.listRuns()- Python
rules.list_runs()- CLI
openemail rules list-runs
rules.list_all_runs
Collect every matching rule run into one array
list_all_runs(rule_id: nil, thread_id: nil, limit: nil, cursor: nil, api_key: nil) -> Array<Hash>Walks every page of the rule audit log and returns all matching runs, newest first. Unlike rules, runs are not capped: a busy rule can leave thousands of rows, so narrow with rule_id: or thread_id: before collecting, and prefer iterate_runs when you can stop early.
Pages are keyset on createdAt and id, walking backwards in time. Runs recorded after the walk starts are newer than its first page and are not included.
پارامترها
rule_idStringOnly runs of this rule, including a rule that has since been deleted.
thread_idStringOnly runs recorded against this thread.
limitIntegerPage size for each request, 1 to 100. The server defaults to 25.
cursorStringStarts the walk from this cursor instead of the newest run.
api_keyStringOverrides the client API key for every page of this walk.
خروجی
An Array of run Hashes holding every matching run, newest first.
نمونه
runs = client.rules.list_all_runs(rule_id: "rul_4f1c9a2b7d3e8f6a0b5c1d2e", limit: 100) refused = runs.select { |run| run[:failures].any? } puts "#{refused.length} of #{runs.length} matches were partly refused"نکتهها
If any page fails the call raises, and the runs already fetched are discarded.
Without a filter this reads the whole mailbox audit, one request per page.
همچنین در دسترس در
- API
GET /rules/runs- TypeScript
rules.listAllRuns()- Python
rules.list_all_runs()
rules.iterate_runs
Stream rule runs one at a time, newest first
iterate_runs(rule_id: nil, thread_id: nil, limit: nil, cursor: nil, api_key: nil, &block) -> Enumerator<Hash>Returns an Enumerator over the rule audit log that yields runs individually, or yields each one to a block when given one, and fetches the next page only when the current one is drained. Without a block nothing is requested until you consume it, and breaking out of the loop stops further requests, which makes it the right way to find the latest run of some kind without reading the whole history.
The walk ends when has_more? is false, when a page carries no next_cursor, or when the server repeats a cursor. Runs recorded after the walk starts are newer than its cursor and are not yielded.
پارامترها
rule_idStringOnly runs of this rule, including a rule that has since been deleted.
thread_idStringOnly runs recorded against this thread.
limitIntegerPage size per request, 1 to 100. The server defaults to 25.
cursorStringStarts the walk from this cursor instead of the newest run.
api_keyStringOverrides the client API key for every page of this walk.
خروجی
An Enumerator of run Hashes (or yields each one to a block), one run per step.
نمونه
client.rules.iterate_runs(rule_id: "rul_4f1c9a2b7d3e8f6a0b5c1d2e") do |run| next unless run[:failures].any? { |failure| failure.start_with?("forward:") } p run[:createdAt], run[:threadId], run[:failures] breakendنکتهها
A page request that fails raises out of the loop, after every run of the pages before it has been yielded.
همچنین در دسترس در
- API
GET /rules/runs- TypeScript
rules.iterateRuns()- Python
rules.iterate_runs()