{"id":13451456,"url":"https://github.com/djsudduth/keep-it-markdown","last_synced_at":"2025-05-15T17:05:38.770Z","repository":{"id":37566562,"uuid":"306197249","full_name":"djsudduth/keep-it-markdown","owner":"djsudduth","description":"Convert Google Keep notes dynamically to markdown for Obsidian, Logseq, Joplin and Notion using the unofficial Keep API. Also, import simple markdown notes back into Google Keep.","archived":false,"fork":false,"pushed_at":"2025-05-14T02:22:21.000Z","size":550,"stargazers_count":554,"open_issues_count":7,"forks_count":33,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-14T03:55:37.398Z","etag":null,"topics":["google-keep","joplin","keep","keep-to-markdown","logseq","markdown","markdown-converter","note-taking","notion","obsidian","obsidian-md","typora","zettelkasten","zettlekasten"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djsudduth.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","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":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"donsuddutha","thanks_dev":null,"custom":null}},"created_at":"2020-10-22T02:07:29.000Z","updated_at":"2025-05-07T06:41:02.000Z","dependencies_parsed_at":"2024-01-06T20:46:20.063Z","dependency_job_id":"0e41b6e1-b5e1-49ee-b88c-3e63f20766d6","html_url":"https://github.com/djsudduth/keep-it-markdown","commit_stats":{"total_commits":193,"total_committers":5,"mean_commits":38.6,"dds":0.03626943005181349,"last_synced_commit":"afb287c25c8e0f4bb28e1a1ad811c0c6626d682f"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djsudduth%2Fkeep-it-markdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djsudduth%2Fkeep-it-markdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djsudduth%2Fkeep-it-markdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djsudduth%2Fkeep-it-markdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djsudduth","download_url":"https://codeload.github.com/djsudduth/keep-it-markdown/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254384988,"owners_count":22062422,"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":["google-keep","joplin","keep","keep-to-markdown","logseq","markdown","markdown-converter","note-taking","notion","obsidian","obsidian-md","typora","zettelkasten","zettlekasten"],"created_at":"2024-07-31T07:00:54.127Z","updated_at":"2025-05-15T17:05:33.759Z","avatar_url":"https://github.com/djsudduth.png","language":"Python","readme":"[![\"Buy Me A Coffee\"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/donsuddutha)  \n[![GitHub license](https://img.shields.io/github/license/djsudduth/keep-it-markdown)](https://github.com/djsudduth/keep-it-markdown/blob/main/LICENSE)   \n# keep-it-markdown\nKeep-it-markdown or KIM converts Google Keep notes to markdown using the unofficial Python Keep API without having to use Google Takeout to export notes first. KIM can now also **import** markdown notes back to Keep. The script will execute on Windows, MacOS or Linux.\n\nThe overall goal is to utilize Google Keep as an easy way to capture raw notes on all devices or additionally using the browser plugin. Then, notes can be queried for export to markdown files directly into notetaking apps such as Obsidian, Logseq and/or Notion, or used directly with Typora. \n\n## Installation\n**Advanced Users:** see the **INSTALL.md** to skip over these installation details for simple step-by-steps  \n\nInstall assumes you have some familiarity with running scripts through a terminal or command line. KIM is a command line script that **requires Python 3.10 or greater** and utilizes the unofficial gkeepapi. (**If you have Python versions 3.10+ and have login issues you may need to review Advanced Docker Setup below**)\n\n**NOTE: Be aware that 'unofficial' implies that Google could change the API at any time that might stop the script from working!**\n\nYou only need to run installation steps 1 through 6 one time.\n\n#### Step 1: \nInstall Python (there are plenty of tutorials online for installation instructions) on you PC or Mac. If you have an older version of Python (3.8 or 3.9) installed and you want to leave it, you can install pyenv to run multiple versions. Start your command prompt, shell or terminal and verify your python version by running:\n```bash\n\u003e python --version\n```\nIf you had Python 2 installed already you may need to type 'python3' instead of just 'python' for the rest of these steps to use version 3.10+.\n\n#### Step 2: \nDownload this project's zip file into any new directory of you choice. Select the most current release noted at the top right of this page and download 'Source code' using this link:  \nhttps://github.com/djsudduth/keep-it-markdown/releases\n\nUnzip the files within your chosen directory.\n\n#### Step 3:\nMake sure you are in your KIM directory and install all needed dependencies with:  \n```bash\n\u003e pip install -r requirements.txt\n```\n(you may need to use 'pip3' instead of 'pip' if you have both python versions 2 and 3 installed) This will install the additional libraries needed to run KIM. You only need to do this once. If you have Anaconda as your Python base you may need to find tutorials on how to get pip and install dependencies. Advanced users may want to setup a virtual environment for this.\n\n#### Step 4:\nKIM requires a Google Keep authentication token in order to run. The token can only be retrieved once you have a Google page OAuth cookie. Install the Chrome extension called 'Cookie Tab Viewer'. Change the directory to where you installed KIM.  \n\nHere's the tricky part - you need to get your OAuth token from a Google cookie. To get the OAuth token - follow the **\"Second way\"** instructions here (but get the cookie value using the Chrome extension once you've pressed \"I agree\" on the Google page in the Second way method):\nhttps://github.com/rukins/gpsoauth-java?tab=readme-ov-file  \n\nCopy the cookie called `oauth_token` using the Chrome Cookie Tab Viewer from the cookies in your local browser. Then, run the script\n```bash\n\u003e python get_token.py\n```\nYou will be prompted for your Google email account name, OAuth token, and Android ID\n\nThe AndroidID can just be a random value like: `abcdef123`  \n\nSo, when you get the prompt when running the script:  \n**Email:** your google ID  \n**OAuth Token:** oauth2_4/......rest of token  \n**Android ID:** abcdef123  \n\nThe Keep token should be displayed - it should look like:  \n\"aas_et/FKcp.............lots of characters.....................BjQ=\"  \n\nCopy that token and save it in a safe place! If it didn't work your OAuth token may have expired (takes about 5 min to expire). Run this step again until you get the token.  \n\n#### Step 5: \nYou now need to save your Keep token within the KIM secure keyring\n```bash\n\u003e python kim.py -t \u003cyour long token value here\u003e\n```\nIf you entered your Google email and token correctly, you should see a successful login with the statement -\u003e \"You've succesfully logged into Google Keep!\"\n\n**If this step keeps failing see 'Key Callouts' #9 below, and have issues with the login - see Advanced Docker Setup below or read this note: https://github.com/djsudduth/keep-it-markdown/issues/72**\n\n## Usage\nCongrats! You can now run KIM. Simply start by running:  \n```bash\n\u003e python kim.py\n```\nAfter logging in you should see:\n```bash\n\u003e Enter a keyword search, label search or '--all' to convert Keep notes to md or '--x' to exit:\n```\n\nEntering a query term and pressing Enter will execute your first export of a note or set of notes as individual markdown files from your active note list.\n\n**NOTE: first time you execute, exported md files will be created in a default KIM sub-directory called 'mdfiles' within your install directory. Images are exported into 'media' within the default directory. This can be changed later**. \n\nFor the first test, use a keyword query that returns and converts only a few notes at most (you can do the search in Keep first to see how many notes will be returned by your query/convert term).\n\nYou can convert to md by using a single word, a phrase or by a label. **All queries to convert ignore notes in archive and trash unless you use the option flags below**. KIM will stay active to do more conversions until you just press --x or Ctrl-C.\n\n### Using Settings\nAt first launch KIM will create a **settings.cfg** file in the directory where you chose to install KIM. You can modify these settings with a text editor:\n\n**google_userid** = your-google-account-id (allows you to bypass typing in your id)  \n**output_path** = path to where the output md files are created (if empty it is your install directory). Windows users use forward slashes, e.g. -\u003e c:/md-files/export.  \n**media_path** = location of the exported media files (images, audio) relative to your output_path. If the output_path is /mdexport and media_path is media/data, the media full path will be /mdexport/media/data. Media paths cannot start with /, mount or drive letter.\n\n(For import settings, see the -i switch below)\n\n### Help and Options\nAll KIM options can be discovered using\n```bash\n\u003e python kim.py --help\n```\nAlso see **EXAMPLES.md** for many option combinations  \n\n#### Labels\nSearching for notes by labels just requires the # character in front of the search term like '#MyLabel'. On some operating systems like Linux you may need to enclose the term in quotes.\n\n#### Titles\nExported note titles use Keep titles in conversion as best it can. In many cases Keep notes do not have titles and by default KIM will use the create date-time as the title. If you wish to use the beginning body content for blank Keep titles use\n```bash\n\u003e python kim.py -c\n```\nif the note has no title or text in the body then the date will be used as default.\n\n#### Overwriting or Skipping\nKIM by default does not overwrite markdown files when exporting, principally because Keep notes can have the same titles. KIM will try to rename duplicate notes. However, notes can be overwritten with\n```bash\n\u003e python kim.py -o\n```\nall exported md files will be overwritten. However, if 2 or more Keep notes have the same title, the create date will be appended on the note to be unique.\n\nIf you want to skip or ignore notes that have already been exported then\n```bash\n\u003e python kim.py -s\n```\nwill skip exporting Keep notes to markdown that already exist in the destination directory. If 2 or more Keep notes have the same title and a markdown file already exists with that name, a new export will be created for any exports that do not exist. (Note that overwrite and skip cannot be used at the same time)\n\n#### Logseq Style \nSome markdown systems prefer to have bullets prepended on each paragraph within a note. KIM will attempt to prepend a dash to any Keep note that has 2 linefeeds as well as the first line. You can enable this feature with\n```bash\n\u003e python kim.py -l\n```\n\n#### Joplin Front Matter \nJoplin tags do not use the hashtag format. They are provided as front matter comments within the notes. With this switch KIM will prepend notes with the Joplin front matter comments to preserve tags and dates. You can enable this feature with\n```bash\n\u003e python kim.py -j\n```\n\n#### Filter by Create or Edit Date \nKIM now supports filtering your export by either the created date (`-cd`) or edited date (`-ed`). This can be combined with the other options to export notes only after or before specific dates. Only the greater-than `\u003e` or less-than `\u003c` filters are available. You must provide the `\u003c`|`\u003e` preceeding the date. The date must be in the form `YYYY-MM-DD`. For example, you can filter on any notes created before Dec 9, 2022 with:\n```bash\n\u003e python kim.py -cd \"\u003c 2022-12-09\"\n```\nOr, you can filter on any notes edited after Oct 31, 2023 with:\n```bash\n\u003e python kim.py -ed \"\u003e 2023-10-31\"\n```\n(Note that Linux users my have to use single quotes)\n\n#### Move Notes to Archive After Export  \n**CAUTION! This is the only switch that alters your notes - even if it just an attribute change. Be sure to backup your Keep notes to Google Takeout before using this option!!**  \nIf you have a large number of notes it can be confusing which ones have already been exported. With this switch any exported notes will be moved to the Keep archive. You can enable this feature with\n```bash\n\u003e python kim.py -m\n```\n\n#### Authentication Token Storage\nWhen you run KIM for the first time and log in via your password, it will store your authenticated Google Keep token in your computer's safe storage (macOS - Keychain, Windows Credential Locker and Linux Secret Service or KWallet). You will not need to re-enter your password next time you run KIM.\n\nIf you need to change or reset your access token or don't feel comfortable saving the token in safe storage, just run KIM with the -r flag (NOTE: this has changed from version 0.2.0):\n```bash\n\u003e python kim.py -r\n```\n\n#### Batch Mode\nKIM can run through your own script by using the -b flag. For example, running:\n```bash\n\u003e python kim.py -b 'my search term'\nor\n\u003e python kim.py -b --all\n```\nwill execute KIM without input prompts as long as you have your Google ID in the setting.cfg file and you have stored your Keep access token by running KIM once manually on your device. Be sure the -b flag is the last of all option flags when combining them.\n\n#### Archive Notes\nKIM has an option to export only Keep archive notes. All other note types are ignored with this option\n```bash\n\u003e python kim.py -a\n```\nArchive export can be combined with the -o and -b options. \n\n#### Convert to Wikilinks\nKIM has an option to modify pre-existing Keep note-to-note links that are in markdown format such as `[Other Keep Note](https://keep.google.com/#NOTE/dks7r23ksdf...UI9kshweriuhv)` to just `[[Other Keep Note]]`\n```bash\n\u003e python kim.py -w\n```\nThis is very useful if you're using the *Markdown for Google Keep* plugin and want Wikilinks for note-to-note link in Obsidian or Joplin. \n\n#### Import Notes - EXPERIMENTAL (WARNING - GOOGLE RATE LIMITS)\nKIM now supports importing markdown note files back into Keep using \n```bash\n\u003e python kim.py -i\n```\n**WARNING! Google may lock you out of your account if you attempt to import more than a couple hundred files - use caution!**\n\nThere are a number of restrictions for importing. First, KIM will only import files within a single directory (no subdirectories) and they must have an .md extension. KIM does not support importing any media (images/audio) at this point. Additionally, KIM will not scan files for tags/labels or create new ones. The file create date and update date will be appended to the note (**Windows users note** - if you copy markdown files to a new directory, the create date will reflect the current date rather than the file's original create date - unless you use Robocopy). Only existing labels can be used and those must be setup in the **settings.cfg** file.\n\nTo add the path and desired labels for import in **settings.cfg**, add or update these two additional settings:  \n**input_path** = path to where the input md files are located. Windows users use forward slashes, e.g. -\u003e c:/md-files/import  \n**input_labels** = a list of one or more comma delimited labels without the # leading character - e.g. -\u003e computers, programming (this will tag all of the imported notes with both labels 'computers' and 'programming' within that import directory as long as you have those labels predefined within Keep already)\n\nNOTE: the import switch -i is incompatible with all other switches for export. Be sure to test simple import examples before using this feature!!! \n\n\n#### Combinations\nExample: to export all non-archived notes, using content for blank note titles, with overwriting, preserving Keep label format, Logseq style paragraphs, with create dates \u003e Oct 3, 2023 in batch:\n```bash\n\u003e python kim.py -c -o -p -l -cd \"\u003e 2023-10-03\" -b --all\n```\nNote: skip -s and overwrite -o cannot be used at the same time\n\n### Key callouts\n1. KIM does its best to convert unusual unicode characters where it can to keep the markdown clean but may have some issues with certain captured notes. If KIM crashes during conversion, try to isolate the problem note in Keep to see why it is causing issues.\n2. All label spaces and special characters are hyphenated in conversion for proper tags. For example, if your Keep label is '#key topics', KIM will convert this to '#key-topics' or if it is '#mind*learning' KIM will convert to '#mind-learning' in the markdown file. Underscores are kept intact. Use the `-p` flag to override this and preserve Keep labels as they are.\n3. Note titles are truncated to 100 characters max.\n4. Notes without Keep titles are given titles using the date-time of when the note was created unless the `-c` flag is used. Notes with the same title will have the date-time appended on the original title when converted to not allow overwriting of each other unless the overwrite flag is set. \n5. Running KIM repeatably without the skip or overwrite options or clearing the output path without using a new path will continue to append date-time to the title of each exported note when it detects a note with the same title until it fails if the title is too long. \n6. All notes' exported text are appended by their create date, update date and URL link back to the original Keep note.  \n7. Both standard PNG and JPEG image files are supported. However, not all image types or non-standard formats may export properly. Drawings in Keep should download as PNG files.\n8. Keep uses AAC format for audio recordings. When notes are downloaded the audio is saved as M4A files. It is not known if this format will work on all markdown applications.\n9. There seems to be login issues due to some of the authentication and security library changes with Google and Python. Take a look at this note -\u003e https://github.com/djsudduth/keep-it-markdown/issues/72 or use the Advanced Docker Setup in the next section\n\n## Advanced Docker Setup\nIf you are having difficulty logging in to Google you can use Docker with the preconfigured OS and Python version to access KIM and save your exported notes (see alternative step 12 if you want to save the Keep token on your PC).\n\n**Steps:**\n1) Install Docker on any PC (find the online instructions for your particular operating system)\n2) Startup Docker (or it will autostart on reboot depending on how you installed it)\n3) Go to the command line and run ``docker build -t kim .`` in the directory where you installed KIM (it will take about 5 min to create the image)\n4) Run the Docker image with ``docker run --mount type=bind,source=(your PC's KIM directory)/mdfiles,target=/keep-it-markdown-0.6.5/mdfiles -it kim`` (you will be automatically logged into the Docker image and your PC's directory will be mapped to the Docker image directory)\n5) Change the directory to Kim ``cd keep-it-markdown-0.6.5``  \n6) Follow **Second Way** instructions here to get a copy of the oauth_token cookie value - https://github.com/rukins/gpsoauth-java?tab=readme-ov-file\n7) Run the script in the KIM directory - `python get_token.py`\n8) Enter your Google email account name, oauth_token, and Android ID when prompted (Android ID can be anything, OAuth token expires in about 5 min)\n9) Copy and save the Keep Token value output from `get_token.py` on your PC\n---\n10) For one time or sporatic use, run KIM in Docker with ``python kim.py -t \u003clong token here\u003e`` using the saved Token above (note that in Docker python3 is aliased to python) - your exported notes will be exported to your PC. NOTE, however, that running Docker this way will not save any passwords or exported notes when you exit and you will need use the saved Token each time you use KIM with Docker this way.(Exit the Docker image with ``exit``)\n---\n11) Alternatively, exit the Docker image with ``exit``\n12) Download and install KIM in your current OS\n13) Install KIM dependencies your PC using `pip install -r requirements.txt`\n14) Run KIM with the `-t` switch once to save the Token in your PC keystore (``python kim.py -t \u003clong token here\u003e``)\n15) You can now run KIM on your PC (once you save the token) with Python v-3.10 or higher without having to run these steps again. The Token will be saved in your local PC's keystore\n\n## Obsidian Use\nSince KIM converts Google Keep notes to markdown, you can use some of the Obsidian text markdown features in your Keep notes as you're capturing information. For example, you can begin to cross-link notes in Keep by using the Wikilink double-brackets within a note like this `[[Title of another Keep note]]`. You can also cross-link notes in Keep like `[Other Note](https://keep.google.com/#NOTE/....)` and use the `-w` option to convert note-to-note links like this to wikilinks. Then, when you convert your notes to the Obsidian vault they will be automatically linked. This will also work for block references and other markdown notation. Most markdown types in Keep notes should convert successfully even if Keep cannot render them. KIM will try to map link any of Keep's URLs to markdown format for you or ignore markdown hyperlinks if they are already in the note.\n\n## Logseq Use\nNotes will import into Logseq similar to the Obsidian Use description, however, you need to set your mdfiles path to the `pages` folder in Logseq. For images to render properly be sure to set your media path to `../assets`. Also, to format notes correctly, a switch has been configured (`-l`) to add paragraph bullets within each exported note so Logseq will render them better. Also, namespaces are supported by using the `/` character in Keep titles (example a Keep note title of \"Journal/2024-May\" will export to \"Journal___2024-May.md\" - when opened in Logseq the namespace will be \"Journal/2024-May\").\n\n## Notion Use\nKIM markdown note exports seem to import into Notion successfully. However, Notion STILL fails to import linked image attachments (which seems to be a general Notion md import problem at this time). Notion also ties underlying ids to any cross-linked notes so that there is no automated cross-linking when importing (future feature). Also, tags are not supported in Notion so Keep labels will just be text hashtags within the note which are searchable.\n\n## Joplin Use\nKIM markdown note exports also import very well into Joplin. Using the `-j` flag will add Keep labels as **Joplin front matter** to add them automatically as tags. Most markdown types in Keep notes should convert successfully even if Keep cannot render them. For example, you can begin to cross-link notes in Keep by using the Wikilink double-brackets within a note like this `[[Title of another Keep note]]`. If you have full markdown note-to-note links in Keep like `[Other Note](https://keep.google.com/#NOTE/....)`, add the `-w` flag to convert those to Wikilinks. Wikilinking between Keep notes will automatically convert to standard Joplin markdown note links connecting notes together.\n\n## Typora Use\nKIM tries to adhere to strict markdown to be as compatible as possible.   No issues have been discovered using Typora on KIM markdown exports.\n\n## Feature Todos\n- [x] Add Keep audio and drawing files  \n- [x] Add overwrite flag to replace notes\n- [x] Clean-up code from MVP\n- [ ] Export from Google Takeout Keep backups\n- [ ] Build a simple installer  \n- [ ] Create setup scripts for Windows, macOS and Linux  \n- [ ] Tie Keep notes to Notion links for cross-linking of md imports  \n- [ ] Email notes to Keep   \n- [ ] Roam imports  \n- [x] Docker version  \n\n\n## Thank You\nThanks for trying this markdown converter! I hope you find it useful!\nThere's always room for improvement. Feel free to add questions or issues to the issues list.\n\n\n","funding_links":["https://buymeacoffee.com/donsuddutha","https://www.buymeacoffee.com/donsuddutha"],"categories":["Python","转换工具","Converters","HarmonyOS"],"sub_categories":["开发组件","Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjsudduth%2Fkeep-it-markdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjsudduth%2Fkeep-it-markdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjsudduth%2Fkeep-it-markdown/lists"}