manage your gmail using google apps script
Ukko is a code name for a google apps script runs on google servers. It can get emails in your inbox or use search, looping over email threads and assigning labels based on the email metadata. It's intended be setup via google drive and have time driven trigger.
- Access your google drive, click New and select "Google Apps Script".
- Name the project "Ukko" and paste the contents of modules/ukko.js , exclude
importandexportstatements those are used for testing Ukko locally. - Click "Run" icon at the top of the editor, you will be prompted to grant access to your gmail.
- If there are any messages in your inbox that have header "List-Id" it will create and assign labels.
NOTE:
- Missing labels are created automatically.
- Feel free to delete labels in gmail at any time, they won't be recreated until matching email is processed by Ukko.
- Labels separated by "/" are nested.
- Threads are assigned all labels in the nested chain, for label "lists/my-list/company", following are assigned:
- "lists"
- "lists/my-list"
- "lists/my-list/company"
- Labelled threads are shown at all nesting levels.
NOTE: To automatically "archive" the thread after labels are applied, uncomment following line in modules/ukko.js :
if (labels.length) { inboxThread.moveToArchive() }Expect similar output when executing the script in google apps script "execution log":
from:email@example.com labels:lists/planet-list
from:announce-list@example.com labels:lists/announce-list
from:nothandled@domain labels:
- Click "Clock" icon named "Triggers".
- Click "Add Trigger".
- Make sure "runUkko" is selected along with "Interval" at which Ukko runs.
- Click save and enjoy!
To try ukko locally you will need nodejs and npm installed on your machine.
To pull javascirpt dependencies (see package.json) locally run npm install:
[tomas@dev ukko]$ npm install
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
added 274 packages from 145 contributors and audited 275 packages in 8.068s
56 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilitiesMocha is used for testing, if you have installed mocha globally you can call it directly with mocha, OR via npm test:
[tomas@dev ukko]$ npm run test
> ukko@0.0.1 test /ukko
> mocha
from:announce-list@example.com labels:lists/announce-list/example
from:email@example.com labels:lists/planet-list/example
email filter tests
get regex tests
✓ should return email
✓ should return jira project
✓ should return email
✓ should return list id
✓ should return to name
get labels tests
✓ should return list of labels for header named List-Id
✓ should return list of labels for emails from @github.com
✓ should sublabel @github.com when "To" header is set
✓ should return list of labels for emails from errata@security.com
✓ should return list of labels for emails from team
✓ should return list of labels for emails from some@subdomain.domain.com
✓ should return list of labels for emails for jira
✓ should return list of labels for emails for jira project
✓ should return list of labels for emails for bugzilla
✓ should return list of labels for emails for bugzilla project
✓ should return list of labels for emails for bugzilla project acronym and component
✓ should not break with empty headers
should return list of assigned labels
✓ output list of processed emails with labels applied
run filter tests
✓ output list of processed emails with labels applied
19 passing (17ms)Eslint is used for linting all js code, if you have installed eslint globally you can call it directly with eslint . OR via npm lint:
[tomas@dev ukko]$ npm run lint
> ukko@0.0.1 lint /ukko
> eslint .To run Ukko locally with mock data call node app.js or npm start
[tomas@dev ukko]$ npm start
> ukko@0.0.1 start /ukko
> node app.js
from:Announce list <announce-list@example.com> labels:lists/announce-list/example
from:email@subdomain.example.com labels:lists/planet-list/exampleUkko uses a config-driven rules engine. To add or modify label rules, edit the RULES array in modules/ukko.js.
| Field | Description |
|---|---|
header |
Email header name to check (From, Sender, To, List-Id, X-GitLab-Project, etc.) |
contains |
Substring match against header value |
endswith |
Suffix match against header value |
label |
Static label to assign (or base label for handlers) |
handler |
Name of handler function for dynamic sublabeling |
fallback |
Only apply if no labels matched yet (default: false) |
Match emails from a domain and assign a static label:
{ header: 'From', contains: '@github.com', label: 'github' }Handlers receive (message, baseLabel) and return an array of labels. They can extract dynamic sublabels from other headers:
// Rule config
{ header: 'From', contains: '@github.com', label: 'github', handler: 'github' }
// Handler in HANDLERS object
github: function (message, baseLabel) {
let label = baseLabel
const toValue = message.getHeader('To')
if (toValue) {
const ghProj = getReMatch('to', toValue)
if (ghProj) { label += `/${ghProj}` }
}
return [label]
}Fallback rules only fire when no other rules have matched:
{ header: 'List-Id', label: 'lists', handler: 'mailing_list', fallback: true }Rules with a handler but no contains/endswith always run when the header exists:
{ header: 'X-GitLab-Project', label: 'gitlab', handler: 'gitlab_project' }- PR are most welcome!
- Please check "issues"
- Read and follow CODE_OF_CONDUCT.md
- Licensed under MIT license
- Clone the repo and raise a pull request
- Love and light