Add delete and archive rule actions
This commit is contained in:
parent
d992ad9c55
commit
fa62afa50e
4 changed files with 16 additions and 5 deletions
|
@ -17,7 +17,7 @@ message meets a specified criterion.
|
||||||
- **Markdown conversion** – optionally convert HTML bodies to Markdown before sending them to the AI service.
|
- **Markdown conversion** – optionally convert HTML bodies to Markdown before sending them to the AI service.
|
||||||
- **Debug logging** – optional colorized logs help troubleshoot interactions with the AI service.
|
- **Debug logging** – optional colorized logs help troubleshoot interactions with the AI service.
|
||||||
- **Light/Dark themes** – automatically match Thunderbird's appearance with optional manual override.
|
- **Light/Dark themes** – automatically match Thunderbird's appearance with optional manual override.
|
||||||
- **Automatic rules** – create rules that tag, move, copy, mark read/unread or flag/unflag messages based on AI classification. Rules can optionally apply only to unread messages.
|
- **Automatic rules** – create rules that tag, move, copy, delete, archive, mark read/unread or flag/unflag messages based on AI classification. Rules can optionally apply only to unread messages.
|
||||||
- **Rule ordering** – drag rules to prioritize them and optionally stop processing after a match.
|
- **Rule ordering** – drag rules to prioritize them and optionally stop processing after a match.
|
||||||
- **Context menu** – apply AI rules from the message list or the message display action button.
|
- **Context menu** – apply AI rules from the message list or the message display action button.
|
||||||
- **Status icons** – toolbar icons show when classification is in progress and briefly display success or error states.
|
- **Status icons** – toolbar icons show when classification is in progress and briefly display success or error states.
|
||||||
|
@ -70,7 +70,7 @@ Sortana is implemented entirely with standard WebExtension scripts—no custom e
|
||||||
|
|
||||||
1. Open the add-on's options and set the URL of your classification service.
|
1. Open the add-on's options and set the URL of your classification service.
|
||||||
2. Use the **Classification Rules** section to add a criterion and optional
|
2. Use the **Classification Rules** section to add a criterion and optional
|
||||||
actions such as tagging or moving a message when it matches. Drag rules to
|
actions such as tagging, moving, copying, deleting or archiving a message when it matches. Drag rules to
|
||||||
reorder them, check *Only apply to unread messages* to skip read mail, and
|
reorder them, check *Only apply to unread messages* to skip read mail, and
|
||||||
check *Stop after match* to halt further processing.
|
check *Stop after match* to halt further processing.
|
||||||
3. Save your settings. New mail will be evaluated automatically using the
|
3. Save your settings. New mail will be evaluated automatically using the
|
||||||
|
@ -102,7 +102,7 @@ Here are some useful and fun example criteria you can use in your filters. Filte
|
||||||
For when you're ready to filter based on vibes.
|
For when you're ready to filter based on vibes.
|
||||||
|
|
||||||
You can define as many filters as you'd like, each using a different prompt and
|
You can define as many filters as you'd like, each using a different prompt and
|
||||||
triggering tags, moves, copies, read/unread changes or flag updates based on the model's classification.
|
triggering tags, moves, copies, deletes, archives, read/unread changes or flag updates based on the model's classification.
|
||||||
|
|
||||||
## Required Permissions
|
## Required Permissions
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
,"action.read": { "message": "read" }
|
,"action.read": { "message": "read" }
|
||||||
,"action.flag": { "message": "flag" }
|
,"action.flag": { "message": "flag" }
|
||||||
,"action.copy": { "message": "copy" }
|
,"action.copy": { "message": "copy" }
|
||||||
|
,"action.delete": { "message": "delete" }
|
||||||
|
,"action.archive": { "message": "archive" }
|
||||||
,"param.markRead": { "message": "mark read" }
|
,"param.markRead": { "message": "mark read" }
|
||||||
,"param.markUnread": { "message": "mark unread" }
|
,"param.markUnread": { "message": "mark unread" }
|
||||||
,"param.flag": { "message": "flag" }
|
,"param.flag": { "message": "flag" }
|
||||||
|
|
|
@ -243,6 +243,10 @@ async function processMessage(id) {
|
||||||
await messenger.messages.update(id, { read: !!act.read });
|
await messenger.messages.update(id, { read: !!act.read });
|
||||||
} else if (act.type === 'flag') {
|
} else if (act.type === 'flag') {
|
||||||
await messenger.messages.update(id, { flagged: !!act.flagged });
|
await messenger.messages.update(id, { flagged: !!act.flagged });
|
||||||
|
} else if (act.type === 'delete') {
|
||||||
|
await messenger.messages.delete([id]);
|
||||||
|
} else if (act.type === 'archive') {
|
||||||
|
await messenger.messages.archive([id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rule.stopProcessing) {
|
if (rule.stopProcessing) {
|
||||||
|
|
|
@ -171,7 +171,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
const typeWrapper = document.createElement('div');
|
const typeWrapper = document.createElement('div');
|
||||||
typeWrapper.className = 'select is-small mr-2';
|
typeWrapper.className = 'select is-small mr-2';
|
||||||
const typeSelect = document.createElement('select');
|
const typeSelect = document.createElement('select');
|
||||||
['tag','move','copy','junk','read','flag'].forEach(t => {
|
['tag','move','copy','junk','read','flag','delete','archive'].forEach(t => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = t;
|
opt.value = t;
|
||||||
opt.textContent = t;
|
opt.textContent = t;
|
||||||
|
@ -242,6 +242,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
sel.value = String(action.flagged ?? true);
|
sel.value = String(action.flagged ?? true);
|
||||||
wrap.appendChild(sel);
|
wrap.appendChild(sel);
|
||||||
paramSpan.appendChild(wrap);
|
paramSpan.appendChild(wrap);
|
||||||
|
} else if (typeSelect.value === 'delete' || typeSelect.value === 'archive') {
|
||||||
|
paramSpan.appendChild(document.createElement('span'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,6 +375,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
if (type === 'flag') {
|
if (type === 'flag') {
|
||||||
return { type, flagged: row.querySelector('.flag-select').value === 'true' };
|
return { type, flagged: row.querySelector('.flag-select').value === 'true' };
|
||||||
}
|
}
|
||||||
|
if (type === 'delete' || type === 'archive') {
|
||||||
|
return { type };
|
||||||
|
}
|
||||||
return { type };
|
return { type };
|
||||||
});
|
});
|
||||||
const stopProcessing = ruleEl.querySelector('.stop-processing')?.checked;
|
const stopProcessing = ruleEl.querySelector('.stop-processing')?.checked;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue