| name | evernote-core-workflow-a |
| description | Execute Evernote primary workflow: Note Creation and Management.
Use when creating notes, organizing content, managing notebooks,
or implementing note-taking features.
Trigger with phrases like "create evernote note", "evernote note workflow",
"manage evernote notes", "evernote content".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*), Grep |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Evernote Core Workflow A: Note Creation & Management
Overview
Primary workflow for creating, organizing, and managing notes in Evernote. This covers the essential CRUD operations that form the foundation of any Evernote integration.
Prerequisites
- Completed
evernote-install-auth setup
- Understanding of ENML format
- Valid access token configured
Instructions
Step 1: Note Creation Service
const Evernote = require('evernote');
class NoteService {
constructor(noteStore) {
this.noteStore = noteStore;
}
async createNote({ title, content, notebookGuid, tagNames = [] }) {
const note = new Evernote.Types.Note();
note.title = this.sanitizeTitle(title);
note.content = this.wrapInENML(content);
if (notebookGuid) {
note.notebookGuid = notebookGuid;
}
if (tagNames.length > 0) {
note.tagNames = tagNames;
}
return this.noteStore.createNote(note);
}
async createTextNote(title, text, notebookGuid = null) {
const content = this.textToENML(text);
return this.createNote({ title, content, notebookGuid });
}
async createHtmlNote(title, html, notebookGuid = null) {
const content = this.htmlToENML(html);
return this.createNote({ title, content, notebookGuid });
}
async createChecklistNote(title, items, notebookGuid = null) {
const checklistHtml = items.map(item => {
if (typeof item === 'string') {
return `<div><en-todo checked="false"/> ${this.escapeHtml(item)}</div>`;
}
return `<div><en-todo checked="${item.checked}"/> ${this.escapeHtml(item.text)}</div>`;
}).join('\n');
return this.createNote({
title,
content: checklistHtml,
notebookGuid
});
}
wrapInENML(content) {
return `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd">
<en-note>
${content}
</en-note>`;
}
textToENML(text) {
const escaped = this.escapeHtml(text).replace(/\n/g, '<br/>');
return this.wrapInENML(`<div>${escaped}</div>`);
}
htmlToENML(html) {
let clean = html
.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '')
.replace(/<form[^>]*>[\s\S]*?<\/form>/gi, '')
.replace(/<iframe[^>]*>[\s\S]*?<\/iframe>/gi, '')
.replace(/\s(class|id|onclick|onload)="[^"]*"/gi, '');
return this.wrapInENML(clean);
}
sanitizeTitle(title) {
return title.replace(/[\r\n]/g, ' ').slice(0, 255);
}
escapeHtml(text) {
return text
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"');
}
}
module.exports = NoteService;
Step 2: Note Retrieval and Reading
class NoteService {
async getNote(noteGuid) {
return this.noteStore.getNote(noteGuid, true, false, false, false);
}
async getNoteWithResources(noteGuid) {
return this.noteStore.getNote(noteGuid, true, true, true, false);
}
async getNoteMetadata(noteGuid) {
return this.noteStore.getNote(noteGuid, false, false, false, false);
}
extractText(enmlContent) {
return enmlContent
.replace(/<\?xml[^>]*\?>/g, '')
.replace(, )
.(, )
.(, )
.(, )
.(, )
.(, )
.(, )
.();
}
() {
.(enmlContent);
}
}
Step 3: Note Updates
class NoteService {
async updateTitle(noteGuid, newTitle) {
const note = await this.getNoteMetadata(noteGuid);
note.title = this.sanitizeTitle(newTitle);
return this.noteStore.updateNote(note);
}
async updateContent(noteGuid, newContent) {
const note = await this.getNoteMetadata(noteGuid);
note.content = this.wrapInENML(newContent);
return this.noteStore.updateNote(note);
}
async appendToNote(noteGuid, additionalContent) {
const note = await this.getNote(noteGuid);
const currentContent = note.content;
const newContent = currentContent.replace(
,
);
note. = newContent;
..(note);
}
() {
note = .(noteGuid);
existingTags = note. || [];
note. = [... ([...existingTags, ...tagNames])];
..(note);
}
() {
note = .(noteGuid);
note. = notebookGuid;
..(note);
}
() {
note = .(noteGuid);
content = note.;
count = ;
content = content.(, {
(count === todoIndex) {
newChecked = checked === ? : ;
count++;
;
}
count++;
match;
});
note. = content;
..(note);
}
}
Step 4: Note Organization
class NotebookService {
constructor(noteStore) {
this.noteStore = noteStore;
}
async listNotebooks() {
return this.noteStore.listNotebooks();
}
async getDefaultNotebook() {
return this.noteStore.getDefaultNotebook();
}
async createNotebook(name, stack = null) {
const notebook = new Evernote.Types.Notebook();
notebook.name = name;
if (stack) {
notebook.stack = stack;
}
return this.noteStore.createNotebook(notebook);
}
async ensureNotebook(name, stack = null) {
const notebooks = await this.listNotebooks();
existing = notebooks.(
n..() === name.()
);
existing || .(name, stack);
}
() {
notebooks = .();
notebooks.(
n..() === name.()
);
}
() {
notebooks = .();
groups = {};
notebooks.( {
stack = nb. || ;
(!groups[stack]) {
groups[stack] = [];
}
groups[stack].(nb);
});
groups;
}
}
Step 5: Complete Workflow Example
const Evernote = require('evernote');
const NoteService = require('./services/note-service');
const NotebookService = require('./services/notebook-service');
async function noteManagementWorkflow(accessToken) {
const client = new Evernote.Client({
token: accessToken,
sandbox: true
});
const noteStore = client.getNoteStore();
const noteService = new NoteService(noteStore);
const notebookService = new NotebookService(noteStore);
const workNotebook = await notebookService.ensureNotebook('Work', 'Projects');
console.log('Using notebook:', workNotebook.name);
const meetingNote = await noteService.createNote({
title: 'Team Standup - ' + new ().(),
: ,
: workNotebook.,
: [, , ]
});
.(, meetingNote.);
taskNote = noteService.(
,
[
{ : , : },
{ : , : },
{ : , : },
{ : , : }
],
workNotebook.
);
.(, taskNote.);
noteService.(meetingNote., );
.();
noteService.(taskNote., );
.();
{
meetingNote,
taskNote,
: workNotebook
};
}
. = noteManagementWorkflow;
Output
- Fully functional note creation service
- ENML content formatting
- Notebook organization
- Tag management
- Todo list support
- Content append/update operations
Error Handling
| Error | Cause | Solution |
|---|
BAD_DATA_FORMAT | Invalid ENML | Use wrapInENML helper, validate content |
LIMIT_REACHED | Too many notebooks (250 max) | Clean up unused notebooks |
DATA_REQUIRED | Missing title or content | Validate inputs before API call |
INVALID_USER | Token expired | Re-authenticate user |
Best Practices
- Always validate ENML before sending to API
- Use tagNames (strings) not tagGuids for simplicity
- Batch read-then-update operations to avoid conflicts
- Handle rate limits with exponential backoff
- Keep note titles under 255 characters
Resources
Next Steps
For search and retrieval workflows, see evernote-core-workflow-b.