{"id":15646879,"url":"https://github.com/azu/memory-note","last_synced_at":"2025-07-04T14:37:32.971Z","repository":{"id":66143479,"uuid":"401059478","full_name":"azu/memory-note","owner":"azu","description":"Fast memory note on CDN edge. Cloudflare Workers KV/GitHub Projects as backend.","archived":false,"fork":false,"pushed_at":"2023-08-22T02:55:49.000Z","size":2745,"stargazers_count":50,"open_issues_count":0,"forks_count":9,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-25T07:45:38.950Z","etag":null,"topics":["api","cloudflare","githubproject","ios","mac","notes"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/azu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"azu"}},"created_at":"2021-08-29T14:16:02.000Z","updated_at":"2024-12-25T03:59:37.000Z","dependencies_parsed_at":"2024-10-03T12:16:26.565Z","dependency_job_id":"848d6756-c492-4266-acbe-232b479e1879","html_url":"https://github.com/azu/memory-note","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azu%2Fmemory-note","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azu%2Fmemory-note/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azu%2Fmemory-note/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/azu%2Fmemory-note/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/azu","download_url":"https://codeload.github.com/azu/memory-note/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242650900,"owners_count":20163610,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","cloudflare","githubproject","ios","mac","notes"],"created_at":"2024-10-03T12:15:33.916Z","updated_at":"2025-03-09T05:31:02.270Z","avatar_url":"https://github.com/azu.png","language":"TypeScript","readme":"# Memory Note\n\nFast memory note for your brain.\n\nMemory Note is an app like reminder.app, but it does not have frontend.\nYou can create and customize frontend and backend.\n\nIn other words, Memory Note is programmable todo-app middleware.\n\n## Features\n\n- Fast - Work on CDN Edges\n    - Memory Notes works on [Cloudflare Workers](https://workers.cloudflare.com/)\n- Customizable Backend - Create own backend\n    - You can use Cloudflare Worker KV or GitHub Projects as backend\n    - Also, you can create own backend by implementing 3 APIs\n- Flexible Frontend - Memory Notes interface is just REST API. You can create any frontend\n    - iOS shortcut.app, iOS Widgets, Alfred Workflow\n\n![Overview](docs/img/overview.png)\n\n### Screenshots\n\n![GitHub Project Board](docs/img/github-project-board.png)\n\n\u003e use GitHub Project Board as backend\n\n![iOS Widget](docs/img/ios-widget.jpeg)\n\n\u003e iOS Widgets using [Web Widget](https://apps.apple.com/jp/app/web-widget-webpage-screenshot/id1561605396) and Siri\n\u003e integrations\n\n![mac Alfred](docs/img/mac-alfred.png)\n\n\u003e Alfred workflow integration\n\n## Usage\n\nRequirements: [Cloudflare](https://www.cloudflare.com/) account\n\n1.\nClick [![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/azu/memory-note)\n2. Deploy memory-note\n3. Set *Environment Variables* to your Memory Note workers\n\n- You need to choose a backend from `cloudflare` or `github` for your Memory Note\n\n### Environment Variables\n\n- `MEMORY_NOTE_TOKEN`: It is random value. This is used for authorization.\n    - You need to access your memory note using `?token=\u003cMEMORY_NOTE_TOKEN\u003e`.\n    - You can use random password generator like \u003chttps://www.lastpass.com/features/password-generator\u003e\n- `BACKEND_SERVICE`: backend service\n    - `github` or `cloudflare` is supported\n    - Default: `cloudflare`\n- Other vars is defined in each Backend Service\n\n:memo: all values should be encrypted.\n\n### Backend Service\n\nCurrently, Memory Note supports following backend:\n\n- `cloudflare`: Cloudflare Workers KV\n- `github`: GitHub Project Board\n- `notion`: Notion\n\nYou can choose a backend.\n\n:memo: If you want to add new backend, please submit Pull Request!\n\n[StorageAdapter.ts](./src/note/StorageAdapter.ts) is an interface for backend.\n\n#### `cloudflare` backend\n\nYou need to create KV Binding.\n\n1. Visit `https://dash.cloudflare.com/{your account id}/workers/kv/namespaces`\n2. Add new Namespace like `MY_MEMORY_NOTE`\n3. Visit `https://dash.cloudflare.com/{your account id}/workers/view/memory-note/settings`\n4. Add new KV Namespace Bindings\n    - `Variable name`: `MEMORY_NOTE`\n    - `KV namespace`: created KV Namespace(`MY_MEMORY_NOTE`)\n\n![kv-namspace-binding](docs/img/kv-namspace-binding.png)\n\n5. Add new Environment Variables\n\n- `MEMORY_NOTE_TOKEN`\n    - `Variable name`: `MEMORY_NOTE_TOKEN`\n    - `Value`: your defined random password\n- `BACKEND_SERVICE`\n    - `Variable name`: `BACKEND_SERVICE`\n    - `Value`: `cloudflare`\n\n#### `github` backend\n\nYou need to create GitHub Projects Board and Get your GitHub API Token\n\n**1. Create Project and Get Column Id**\n\n1. Create a GitHub Repository\n2. Create a GitHub Project on the repository\n    - \u003chttps://docs.github.com/en/issues/organizing-your-work-with-project-boards/managing-project-boards/creating-a-project-board\u003e\n3. Create a column like \"Memory Note\"\n4. Copy Column link\n5. Get Column id from the copied link\n\n![copy-column-link](docs/img/copy-column-link.png)\n\nThis **Column id** is `:listId` value of API endpoint.\n\nFor example, if column link is `https://github.com/yourname/yourrepo/projects/1#column-1111111`, `1111111`\nis `column_id`. You need to copy it.\nYou can use the column id as `:listId`.\n\n```bash\n$ curl https://example-memory-note.worker.dev/notes/1111111?token=random-password\n```\n\n**2. Get GitHub API Token**\n\n1. Visit \u003chttps://github.com/settings/tokens/new\u003e\n2. Create new API Token\n    - permissions: `repo`\n3. Copy it\n\n**3. Add Environments Variables to Cloudflare Workers**\n\nAdd some Environment Variables.\n\nVisit `https://dash.cloudflare.com/{your account id}/workers/view/memory-note/settings`\n\n- `MEMORY_NOTE_TOKEN`\n    - `Variable name`: `MEMORY_NOTE_TOKEN`\n    - `Value`: your defined random password\n- `BACKEND_SERVICE`:\n    - `Variable name`: `BACKEND_SERVICE`\n    - `Value`: `github`\n- `GITHUB_OWNER`:\n    - `Variable name`: `GITHUB_OWNER`\n    - `Value`: your GitHub account name\n- `GITHUB_REPO`:\n    - `Variable name`: `GITHUB_REPO`\n    - `Value`: your GitHub repository name\n- `GITHUB_PROJECT_ID`\n    - `Variable name`: `GITHUB_PROJECT_ID`\n    - `Value`: your GitHub Project id\n- `GITHUB_TOKEN`\n    - `Variable name`: `GITHUB_TOKEN`\n    - `Value`: your GitHub API token\n\nFor example, if you have used `https://github.com/your/my-note/projects/1` repo, you need to set `GITHUB_OWNER=your`\nand `GITHUB_REPO=my-note`, and `GITHUB_PROJECT_ID=1`.\n\n![github-env](docs/img/github-env.png)\n\n### Notion backend\n\nYou need to create Notion Database and Get your Notion API Token\n\n- `NOTION_TOKEN`=`\"\u003cNOTION API TOKEN\u003e\"`\n- `NOTION_MESSAGE_PROPERTY_NAME`=`\"\u003cTITLE property Name\u003e\"`\n\nYou need to pass Notion Database ID as `:listId` value of API endpoint.\n\n- `GET /notes/\u003cNOTION_DATABASE_ID\u003e`\n- `POST /notes/\u003cNOTION_DATABASE_ID\u003e/new`\n\n````\nhttps://www.notion.so/myworkspace/a8aec43384f447ed84390e8e42c2e089?v=...\n                                  | --------- Database ID --------|\n````\n\n\nOptional:\n\n- `NOTION_FILTER_OPTIONS`=`'{\"name\":\"\u003cPROPERTY_NAME\u003e\",\"type\": \"type\": \"\u003cPROPERTY_TYPE\u003e\", \"value\":\"\u003cPROPERTY_VALUE\u003e\"}'`\n\n`NOTION_FILTER_OPTIONS` is a JSON string of `NotionFilterOption[]`.\nIt will filter notes by `PROPERTY_NAME` and `PROPERTY_VALUE`.\n\n```ts\nexport type NotionFilterOption =\n| {\n  name: string;\n  type: \"checkbox\";\n  value: string;\n}\n| {\n  name: string;\n  type: \"relation\";\n  value: string;\n}\n| {\n  name: string;\n  type: \"select\";\n  value: string;\n  op?: \"equals\" | \"does_not_equal\";\n}\n| {\n  name: string;\n  type: \"status\";\n  value: string;\n  op?: \"equals\" | \"does_not_equal\";\n};\n```\n\nExamples:\n\n```\n# filter category and checkbox\nNOTION_FILTER_OPTIONS='[{\"name\":\"category\",\"type\":\"select\",\"value\":\"test\"},{\"name\":\"done\",\"type\":\"checkbox\",\"value\":false}]'\n```\n\n```\n# filter relation and checkbox\nNOTION_FILTER_OPTIONS='[{\"name\":\"ref\",\"type\":\"relation\",\"value\":\"xxxx-id--id\"},{\"name\":\"done\",\"type\":\"checkbox\",\"value\":false}]'\n```\n\n## API\n\nMemory-Note provides following API.\n\n### `GET /notes/:listId`\n\nReturn an array of notes.\n\nParameters:\n\n- `:listId`: note key. This use-case is defined by adapter.\n    - on `github`: your project column id\n    - on `cloudflare`: any string\n\nQuery:\n\n- `?limit`: result item count\n- `\u0026token`: Your Memory Note token\n\nExample:\n\n```\n# curl https://{your worker}/notes/{your GitHub Project Column Id}?token={your Memory Note Token}\n$ curl https://example-memory-note.worker.dev/notes/11111?token=random-password\n```\n\n### `GET /notes/:listId/txt`\n\ntxt version of `/notes/:listId`.\nThe response is like following:\n\n```\nnote\nnote\nnote\n```\n\n### `GET /notes/:listId/widget`\n\nReturn simple html page for widgets.\n\nYou can show your notes on Widgets app\nlike [Web Widget](https://apps.apple.com/jp/app/web-widget-webpage-screenshot/id1561605396).\n\n### `POST /notes/:listId/new`\n\nPost a note that following json data.\n\n```typescript\ntype NoteBody = {\n    message: string;\n};\n```\n\nExample of post data.\n\n```json\n{\n  \"message\": \"test\"\n}\n```\n\nParameters:\n\n- `:listId`: note key. This use-case is defined by adapter.\n\nQuery:\n\n- `?token`: Your Memory Note token\n\n### `PUT /notes/:listId/:noteId`\n\nEdit a note with the `:noteId`\n\n```typescript\ntype NoteBody = {\n    message: string;\n};\n```\n\nExample of post data.\n\n```json\n{\n  \"message\": \"test\"\n}\n```\n\nParameters:\n\n- `:listId`: note key. This use-case is defined by adapter.\n- `:noteId`: note id. you can get the id from GET api\n\nQuery:\n\n- `?token`: Your Memory Note token\n\n### `DELETE /notes/:listId/:noteId`\n\nDelete the note.\n\nParameters:\n\n- `:listId`: note key. This use-case is defined by adapter.\n- `:noteId`: note id. you can get the id from GET api\n\nQuery:\n\n- `?token`: Your Memory Note token\n\n### `POST /notes/:listId/move/:noteId`\n\nMove the note to another list.\n\n- `:listId`: note key. This use-case is defined by adapter.\n- `:noteId`: note id. you can get the id from GET api\n\nBody:\n\n- `to`: to list id\n\n```shell\n{\n  \"to\": \"another list id\"\n}\n```\n\n## Clients\n\nYou can use client app for Memory Note.\n\n### Alfred\n\nAlfred workflow can show notes in large types, add a new note, remove a note.\n\n- Download [memory-note.workflow](docs/alfred/memory-note.alfredworkflow)\n- Set [Workflow Variables](https://www.alfredapp.com/help/workflows/advanced/variables/)\n\n![alfred-workflow-variables](docs/img/alfred-workflow-variables.png)\n\n[Workflow Variables](https://www.alfredapp.com/help/workflows/advanced/variables/)\n\n- `API_ENDPOINT`: your cloudflare worker url\n    - Example, `https://my-memory-note.you.workers.dev`\n- `API_TOKEN`: your memory note token\n- `LIST_ID`: your main `:listId`\n\n### iOS shortcuts.app:\n\niOS shortcut can create a new note using voice(siri), read out notes.\n\n- Add note using voice to memory note: \u003chttps://www.icloud.com/shortcuts/c1095e066e1b40f9986aa1a5b0e36be8\u003e\n- Read memory note: \u003chttps://www.icloud.com/shortcuts/d05d9b072cf94fffb4215b4e9d4ea6b6\u003e\n\n:memo: You input `worker url` and `:listId` and `memory note token` after installing the workflow\n\n### Others\n\n- [ ] Please submit a Pull Request\n\n## Contributing\n\n1. Fork it!\n2. Create your feature branch: `git checkout -b my-new-feature`\n3. Commit your changes: `git commit -am 'Add some feature'`\n4. Push to the branch: `git push origin my-new-feature`\n5. Submit a pull request :D\n\n## License\n\nMIT\n","funding_links":["https://github.com/sponsors/azu"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazu%2Fmemory-note","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fazu%2Fmemory-note","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fazu%2Fmemory-note/lists"}