Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions apps/docs/components/icons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1806,6 +1806,14 @@ export function Mem0Icon(props: SVGProps<SVGSVGElement>) {
)
}

export function EvernoteIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32' fill='#7fce2c'>
<path d='M29.343 16.818c.1 1.695-.08 3.368-.305 5.045-.225 1.712-.508 3.416-.964 5.084-.3 1.067-.673 2.1-1.202 3.074-.65 1.192-1.635 1.87-2.992 1.924l-3.832.036c-.636-.017-1.278-.146-1.9-.297-1.192-.3-1.862-1.1-2.06-2.3-.186-1.08-.173-2.187.04-3.264.252-1.23 1-1.96 2.234-2.103.817-.1 1.65-.077 2.476-.1.205-.007.275.098.203.287-.196.53-.236 1.07-.098 1.623.053.207-.023.307-.26.305a7.77 7.77 0 0 0-1.123.053c-.636.086-.96.47-.96 1.112 0 .205.026.416.066.622.103.507.45.78.944.837 1.123.127 2.247.138 3.37-.05.675-.114 1.08-.54 1.16-1.208.152-1.3.155-2.587-.228-3.845-.33-1.092-1.006-1.565-2.134-1.7l-3.36-.54c-1.06-.193-1.7-.887-1.92-1.9-.13-.572-.14-1.17-.214-1.757-.013-.106-.074-.208-.1-.3-.04.1-.106.212-.117.326-.066.68-.053 1.373-.185 2.04-.16.8-.404 1.566-.67 2.33-.185.535-.616.837-1.205.8a37.76 37.76 0 0 1-7.123-1.353l-.64-.207c-.927-.26-1.487-.903-1.74-1.787l-1-3.853-.74-4.3c-.115-.755-.2-1.523-.083-2.293.154-1.112.914-1.903 2.04-1.964l3.558-.062c.127 0 .254.003.373-.026a1.23 1.23 0 0 0 1.01-1.255l-.05-3.036c-.048-1.576.8-2.38 2.156-2.622a10.58 10.58 0 0 1 4.91.26c.933.275 1.467.923 1.715 1.83.058.22.146.3.37.287l2.582.01 3.333.37c.686.095 1.364.25 2.032.42 1.165.298 1.793 1.112 1.962 2.256l.357 3.355.3 5.577.01 2.277zm-4.534-1.155c-.02-.666-.07-1.267-.444-1.784a1.66 1.66 0 0 0-2.469-.15c-.364.4-.494.88-.564 1.4-.008.034.106.126.16.126l.8-.053c.768.007 1.523.113 2.25.393.066.026.136.04.265.077zM8.787 1.154a3.82 3.82 0 0 0-.278 1.592l.05 2.934c.005.357-.075.45-.433.45L5.1 6.156c-.583 0-1.143.1-1.554.278l5.2-5.332c.02.013.04.033.06.053z' />
</svg>
)
}

export function ElevenLabsIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg
Expand Down
2 changes: 2 additions & 0 deletions apps/docs/components/ui/icon-mapping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
ElasticsearchIcon,
ElevenLabsIcon,
EnrichSoIcon,
EvernoteIcon,
ExaAIIcon,
EyeIcon,
FirecrawlIcon,
Expand Down Expand Up @@ -202,6 +203,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
elasticsearch: ElasticsearchIcon,
elevenlabs: ElevenLabsIcon,
enrich: EnrichSoIcon,
evernote: EvernoteIcon,
exa: ExaAIIcon,
file_v3: DocumentIcon,
firecrawl: FirecrawlIcon,
Expand Down
267 changes: 267 additions & 0 deletions apps/docs/content/docs/en/tools/evernote.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
---
title: Evernote
description: Manage notes, notebooks, and tags in Evernote
---

import { BlockInfoCard } from "@/components/ui/block-info-card"

<BlockInfoCard
type="evernote"
color="#E0E0E0"
/>

## Usage Instructions

Integrate with Evernote to manage notes, notebooks, and tags. Create, read, update, copy, search, and delete notes. Create and list notebooks and tags.



## Tools

### `evernote_copy_note`

Copy a note to another notebook in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `noteGuid` | string | Yes | GUID of the note to copy |
| `toNotebookGuid` | string | Yes | GUID of the destination notebook |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `note` | object | The copied note metadata |
| ↳ `guid` | string | New note GUID |
| ↳ `title` | string | Note title |
| ↳ `notebookGuid` | string | GUID of the destination notebook |
| ↳ `created` | number | Creation timestamp in milliseconds |
| ↳ `updated` | number | Last updated timestamp in milliseconds |

### `evernote_create_note`

Create a new note in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `title` | string | Yes | Title of the note |
| `content` | string | Yes | Content of the note \(plain text or ENML\) |
| `notebookGuid` | string | No | GUID of the notebook to create the note in \(defaults to default notebook\) |
| `tagNames` | string | No | Comma-separated list of tag names to apply |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `note` | object | The created note |
| ↳ `guid` | string | Unique identifier of the note |
| ↳ `title` | string | Title of the note |
| ↳ `content` | string | ENML content of the note |
| ↳ `notebookGuid` | string | GUID of the containing notebook |
| ↳ `tagNames` | array | Tag names applied to the note |
| ↳ `created` | number | Creation timestamp in milliseconds |
| ↳ `updated` | number | Last updated timestamp in milliseconds |

### `evernote_create_notebook`

Create a new notebook in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `name` | string | Yes | Name for the new notebook |
| `stack` | string | No | Stack name to group the notebook under |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `notebook` | object | The created notebook |
| ↳ `guid` | string | Notebook GUID |
| ↳ `name` | string | Notebook name |
| ↳ `defaultNotebook` | boolean | Whether this is the default notebook |
| ↳ `serviceCreated` | number | Creation timestamp in milliseconds |
| ↳ `serviceUpdated` | number | Last updated timestamp in milliseconds |
| ↳ `stack` | string | Notebook stack name |

### `evernote_create_tag`

Create a new tag in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `name` | string | Yes | Name for the new tag |
| `parentGuid` | string | No | GUID of the parent tag for hierarchy |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `tag` | object | The created tag |
| ↳ `guid` | string | Tag GUID |
| ↳ `name` | string | Tag name |
| ↳ `parentGuid` | string | Parent tag GUID |
| ↳ `updateSequenceNum` | number | Update sequence number |

### `evernote_delete_note`

Move a note to the trash in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `noteGuid` | string | Yes | GUID of the note to delete |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `success` | boolean | Whether the note was successfully deleted |
| `noteGuid` | string | GUID of the deleted note |

### `evernote_get_note`

Retrieve a note from Evernote by its GUID

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `noteGuid` | string | Yes | GUID of the note to retrieve |
| `withContent` | boolean | No | Whether to include note content \(default: true\) |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `note` | object | The retrieved note |
| ↳ `guid` | string | Unique identifier of the note |
| ↳ `title` | string | Title of the note |
| ↳ `content` | string | ENML content of the note |
| ↳ `contentLength` | number | Length of the note content |
| ↳ `notebookGuid` | string | GUID of the containing notebook |
| ↳ `tagGuids` | array | GUIDs of tags on the note |
| ↳ `tagNames` | array | Names of tags on the note |
| ↳ `created` | number | Creation timestamp in milliseconds |
| ↳ `updated` | number | Last updated timestamp in milliseconds |
| ↳ `active` | boolean | Whether the note is active \(not in trash\) |

### `evernote_get_notebook`

Retrieve a notebook from Evernote by its GUID

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `notebookGuid` | string | Yes | GUID of the notebook to retrieve |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `notebook` | object | The retrieved notebook |
| ↳ `guid` | string | Notebook GUID |
| ↳ `name` | string | Notebook name |
| ↳ `defaultNotebook` | boolean | Whether this is the default notebook |
| ↳ `serviceCreated` | number | Creation timestamp in milliseconds |
| ↳ `serviceUpdated` | number | Last updated timestamp in milliseconds |
| ↳ `stack` | string | Notebook stack name |

### `evernote_list_notebooks`

List all notebooks in an Evernote account

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `notebooks` | array | List of notebooks |

### `evernote_list_tags`

List all tags in an Evernote account

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `tags` | array | List of tags |

### `evernote_search_notes`

Search for notes in Evernote using the Evernote search grammar

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `query` | string | Yes | Search query using Evernote search grammar \(e.g., "tag:work intitle:meeting"\) |
| `notebookGuid` | string | No | Restrict search to a specific notebook by GUID |
| `offset` | number | No | Starting index for results \(default: 0\) |
| `maxNotes` | number | No | Maximum number of notes to return \(default: 25\) |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `totalNotes` | number | Total number of matching notes |
| `notes` | array | List of matching note metadata |

### `evernote_update_note`

Update an existing note in Evernote

#### Input

| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | Evernote developer token |
| `noteGuid` | string | Yes | GUID of the note to update |
| `title` | string | No | New title for the note |
| `content` | string | No | New content for the note \(plain text or ENML\) |
| `notebookGuid` | string | No | GUID of the notebook to move the note to |
| `tagNames` | string | No | Comma-separated list of tag names \(replaces existing tags\) |

#### Output

| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `note` | object | The updated note |
| ↳ `guid` | string | Unique identifier of the note |
| ↳ `title` | string | Title of the note |
| ↳ `content` | string | ENML content of the note |
| ↳ `notebookGuid` | string | GUID of the containing notebook |
| ↳ `tagNames` | array | Tag names on the note |
| ↳ `created` | number | Creation timestamp in milliseconds |
| ↳ `updated` | number | Last updated timestamp in milliseconds |


1 change: 1 addition & 0 deletions apps/docs/content/docs/en/tools/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"elasticsearch",
"elevenlabs",
"enrich",
"evernote",
"exa",
"file",
"firecrawl",
Expand Down
38 changes: 38 additions & 0 deletions apps/sim/app/api/tools/evernote/copy-note/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { copyNote } from '@/app/api/tools/evernote/lib/client'

export const dynamic = 'force-dynamic'

const logger = createLogger('EvernoteCopyNoteAPI')

export async function POST(request: NextRequest) {
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success) {
return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
}

try {
const body = await request.json()
const { apiKey, noteGuid, toNotebookGuid } = body

if (!apiKey || !noteGuid || !toNotebookGuid) {
return NextResponse.json(
{ success: false, error: 'apiKey, noteGuid, and toNotebookGuid are required' },
{ status: 400 }
)
}

const note = await copyNote(apiKey, noteGuid, toNotebookGuid)

return NextResponse.json({
success: true,
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
logger.error('Failed to copy note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
}
51 changes: 51 additions & 0 deletions apps/sim/app/api/tools/evernote/create-note/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { createLogger } from '@sim/logger'
import { type NextRequest, NextResponse } from 'next/server'
import { checkInternalAuth } from '@/lib/auth/hybrid'
import { createNote } from '@/app/api/tools/evernote/lib/client'

export const dynamic = 'force-dynamic'

const logger = createLogger('EvernoteCreateNoteAPI')

export async function POST(request: NextRequest) {
const authResult = await checkInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success) {
return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
}

try {
const body = await request.json()
const { apiKey, title, content, notebookGuid, tagNames } = body

if (!apiKey || !title || !content) {
return NextResponse.json(
{ success: false, error: 'apiKey, title, and content are required' },
{ status: 400 }
)
}

const parsedTags = tagNames
? (() => {
const tags =
typeof tagNames === 'string'
? tagNames
.split(',')
.map((t: string) => t.trim())
.filter(Boolean)
: tagNames
return tags.length > 0 ? tags : undefined
})()
: undefined

const note = await createNote(apiKey, title, content, notebookGuid || undefined, parsedTags)

return NextResponse.json({
success: true,
output: { note },
})
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error'
logger.error('Failed to create note', { error: message })
return NextResponse.json({ success: false, error: message }, { status: 500 })
}
}
Loading