{"id":13755252,"url":"https://github.com/kbravh/tweet-to-markdown","last_synced_at":"2025-08-02T04:07:48.834Z","repository":{"id":37254374,"uuid":"293309694","full_name":"kbravh/tweet-to-markdown","owner":"kbravh","description":"A command line tool to convert Tweets to Markdown.","archived":false,"fork":false,"pushed_at":"2023-05-08T13:26:22.000Z","size":310,"stargazers_count":164,"open_issues_count":4,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-07-27T04:17:25.513Z","etag":null,"topics":["cli","foam","markdown","roamresearch","tweet","twitter","twitter-api-v2","zettelkasten"],"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/kbravh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":"kbravh","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-09-06T15:50:36.000Z","updated_at":"2025-03-30T02:10:00.000Z","dependencies_parsed_at":"2023-01-21T07:02:54.268Z","dependency_job_id":"2874a165-1b1c-48c7-9ecf-b0f3cadacada","html_url":"https://github.com/kbravh/tweet-to-markdown","commit_stats":{"total_commits":114,"total_committers":1,"mean_commits":114.0,"dds":0.0,"last_synced_commit":"6e86b49509d92459e75541942ac19a94b69badaa"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kbravh/tweet-to-markdown","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbravh%2Ftweet-to-markdown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbravh%2Ftweet-to-markdown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbravh%2Ftweet-to-markdown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbravh%2Ftweet-to-markdown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kbravh","download_url":"https://codeload.github.com/kbravh/tweet-to-markdown/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kbravh%2Ftweet-to-markdown/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268334089,"owners_count":24233782,"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","status":"online","status_checked_at":"2025-08-02T02:00:12.353Z","response_time":74,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cli","foam","markdown","roamresearch","tweet","twitter","twitter-api-v2","zettelkasten"],"created_at":"2024-08-03T10:00:49.996Z","updated_at":"2025-08-02T04:07:48.800Z","avatar_url":"https://github.com/kbravh.png","language":"TypeScript","funding_links":["https://ko-fi.com/kbravh"],"categories":["TypeScript","HarmonyOS","Credits"],"sub_categories":["Windows Manager","Open Source"],"readme":"\u003c!-- PROJECT SHIELDS --\u003e\n\u003c!-- [![Contributors][contributors-shield]][contributors-url] --\u003e\n\u003c!-- [![Forks][forks-shield]][forks-url] --\u003e\n\n[![Stargazers][stars-shield]][stars-url]\n[![Issues][issues-shield]][issues-url]\n[![MIT License][license-shield]][license-url]\n\n\u003cbr /\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/kbravh/tweet-to-markdown\"\u003e\n    \u003cimg src=\"images/tweet-to-markdown-logo.svg\" alt=\"Logo\" height=50\u003e\n  \u003c/a\u003e\n\n  \u003ch3 align=\"center\"\u003eTweet to Markdown\u003c/h3\u003e\n\n  \u003cp align=\"center\"\u003e\n    A command line tool to quickly save tweets as Markdown.\n    \u003cbr /\u003e\n    \u003cbr /\u003e\n    \u003ca href=\"https://github.com/kbravh/tweet-to-markdown/issues\"\u003eReport a Bug\u003c/a\u003e\n    ·\n    \u003ca href=\"https://github.com/kbravh/tweet-to-markdown/issues\"\u003eRequest a Feature\u003c/a\u003e\n  \u003c/p\u003e\n\u003c/p\u003e\n\n## ⚠️ Heads up! ⚠️\n\nIf your API key is not working, you will need to apply for a Twitter bearer token.\n\nDue to recent changes to the Twitter API, the free access method listed below has stopped working as of April 27, 2023. You must sign up for your own Twitter bearer token to use this application.\n\n\u003c!-- ABOUT THE PROJECT --\u003e\n\n## About The Project\n\nThis command line tool allows you to quickly save a tweet in Markdown format. This is great for Zettelkasten note-taking or any other commonplace notebook, vade mecum, Obsidian, Roam, Foam, \u0026c. It is built on the new Twitter v2 API.\n\n![Demo of `ttm` in the command line](./images/ttm_demo.gif)\n\n## Installing\n\n⚠ **You'll need to have Node.js of at least `v12.x` to use this tool.**\n\nYou can install this CLI tool by running\n\n```bash\nyarn global add tweet-to-markdown\n```\n\nor\n\n```bash\nnpm install --global tweet-to-markdown\n```\n\nYou can also run it without installing:\n\n```bash\nnpx tweet-to-markdown\n```\n\n\u003c!-- USAGE EXAMPLES --\u003e\n\n## Setup\n\nTo use this tool, you have ~~two~~ options:\n\n- ~~Sign up for a free API key from https://ttm.kbravh.dev (new in v2.0.0)~~\n- Sign up for a bearer token through the Twitter Developer dashboard\n\n### Free TTM API key (❌ disabled)\n\n~~You can sign up for a free API key at https://ttm.kbravh.dev by signing in with either your GitHub or Twitter account and heading to your account page. Once you sign in and retrieve your API key from your account page, either store it in the environment variable `TTM_API_KEY` or pass it to the command line tool with the `-b` (`--bearer`) flag with each call.~~\n\n### Twitter Developer bearer token\n\nNota bene: You need at least a **Basic** plan in order to look up tweets. The **Free** plan is not sufficient.\n\nTo get a bearer token from Twitter, you'll need to set up an application on the [Twitter developer dashboard](https://developer.twitter.com/en/portal/dashboard). For a guide on doing so, see [Getting a bearer token](https://github.com/kbravh/obsidian-tweet-to-markdown/blob/main/BearerTokenGuide.md). Once you have the bearer token, either store it in the environment variable `TWITTER_BEARER_TOKEN` or pass it to the command line tool with the `-b` (`--bearer`) flag with each call.\n\n## Usage\n\nGrabbing a tweet is as easy as calling the `ttm` command and passing in the tweet URL.\n\n```bash\nttm -b \"\u003cbearer token\u003e\" https://twitter.com/JoshWComeau/status/1213870628895428611\n# Tweet saved as JoshWComeau - 1213870628895428611.md\n```\n\nNota bene: If passing your bearer token as an argument instead of an environment variable, wrap your bearer token or API key in quotes to prevent any special symbols from being misinterpreted by the command line. Also, if using a TTM API key, be sure to include the entire key, from the `TTM` at the beginning all the way to the end with the alphanumeric characters (e.g. `\"TTM\u003easdf1123\"` or `\"TTM_ghjk4567\"`).\n\nThe tweet will be saved to a Markdown file in the current directory. Here's how the tweet will look:\n\n![Screenshot of the rendered Markdown file](images/tweet-markdown-screenshot.png)\n\nAny attached images, polls, and links will also be linked and displayed in the file.\n\n## Options\n\nThere are _many_ options to customize how this tool works. It is highly recommended to find the options you need and set up an alias in your terminal.\n\nFor example on Mac or Linux, you can define an alias with your options like so:\n\n```bash\nalias ttm=\"ttm -p $HOME/notes --assets --quoted\"\n```\n\nFor Windows, have a look at [DOSKEY](https://superuser.com/a/560558).\n\n### Copy to Clipboard\n\nWhat if you want to just copy the Markdown to the clipboard instead of saving to a file? Just pass the `-c` (`--clipboard`) flag.\n\n```bash\nttm -c https://twitter.com/JoshWComeau/status/1213870628895428611\n#Tweet copied to the clipboard.\n```\n\n### Quoted tweets\n\nIf you would like to include quoted tweets, pass the `-q` (`--quoted`) flag. This is disabled by default because a separate request has to be made to fetch the quoted tweet.\n\n```bash\nttm \u003ctweet url\u003e -q\n```\n\n### Tweet threads\n\nTo capture an entire tweet thread, use the `-t` (`--thread`) flag and pass the URL of the **last** tweet in the thread.\n\nNota bene: this will make a separate network request for each tweet.\n\n```bash\nttm \u003clast tweet url\u003e -t\n```\n\n#### Condensed threads\n\nInstead of showing complete, individual tweets with profile picture, date, etc. when downloading a thread, this option will show the header once and then only show the tweet bodies, representing tweet threads as a cohesive body of text. A header will be shown if a different author appears in the thread, for example if you're downloading a conversation between various authors.\n\n```bash\nttm \u003clast tweet url\u003e -T\n```\n\n#### Semicondensed threads\n\nThese follow the same rules as condensed threads, but each tweet will still be separated by `---`.\n\n```bash\nttm \u003clast tweet url\u003e -s\n```\n\n### Text only\n\nWith this flag, only the text of the tweet itself will be included. No author tags, frontmatter, or other information will be attached.\n\nNota bene: This has not been tested well with threads. Please use at your own risk. Condensed threads may be a better fit for you.\n\n### Custom File Name\n\nIn order to save the tweet with a custom filename, pass the desired name to the `--filename` flag. You can use the variables `[[name]]`, `[[handle]]`, `[[text]]`, and `[[id]]` in your filename, which will be replaced according to the following chart. The file extension `.md` will also be added automatically.\n\n|  Variable  | Replacement                                                                     |\n| :--------: | ------------------------------------------------------------------------------- | --- |\n| [[handle]] | The user's handle (the part that follows the @ symbol)                          |\n|  [[name]]  | The user's name                                                                 |\n|   [[id]]   | The unique ID assigned to the tweet                                             |\n|  [[text]]  | The entire text of the tweet (truncated to fit OS filename length restrictions) | .   |\n\n```bash\nttm \u003ctweet url\u003e --filename \"[[handle]] - Favicon versioning\".\n# Tweet saved to JoshWComeau - Favicon versioning.md\n```\n\nIf the file already exists, an error will be thrown unless you pass the `-f` (`--force`) flag to overwrite the file.\n\n### Custom File Path\n\nTo save the tweet to a place other than the current directory, pass the location to the `-p` (`--path`) flag. If this path doesn't exist, it will be recursively created.\n\n```bash\nttm \u003ctweet url\u003e -p \"./tweets/\"\n# Tweet saved to ./tweets/JoshWComeau - 1213870628895428611.md\n```\n\n### Tweet Metrics\n\nIf you'd also like to record the number of likes, retweets, and replies the tweet has, pass the `-m` (`--metrics`) flag. This will save those numbers in the frontmatter of the file.\n\n```bash\nttm \u003ctweet url\u003e -m\n```\n\n```yaml\n---\nauthor: Josh ✨\nhandle: @JoshWComeau\nlikes: 993\nretweets: 163\nreplies: 24\n---\n```\n\n### Save Images Locally\n\nWant to really capture the entire tweet locally? You can pass the `-a` (`--assets`) flag to download all the tweet images as well, instead of just linking to the images on the web. If the tweet is ever deleted or Twitter is unavailable, you'll still have your note.\n\n```bash\nttm \u003ctweet url\u003e -a\n```\n\nTweet images will be automatically saved to `./tweet-assets`. If you'd like to save the assets to a custom directory, use the `--assets-path` flag and pass in the directory.\n\n```bash\nttm \u003ctweet url\u003e -a --assets-path \"./images\"\n```\n\nNota bene: Unfortunately, there is currently not a way to save gifs or videos from tweets using the v2 API.\n\n### Date locale\n\nUsing the `--date_locale` option, you can pass a BCP 47 language code to have the date displayed in a specific locale. If you don't pass this option (or if you're using lower than Node 13), your computer's default locale will be used.\n\nFinding a complete list of these language codes is difficult, but here's a short list of examples:\n| Tag | Language |\n| --- | --- |\n| en | English |\n| en-US | American English |\n| es-MX | Mexican Spanish |\n| ta-IN | Indian Tamil |\n\nA more complete list can be found here: https://gist.github.com/typpo/b2b828a35e683b9bf8db91b5404f1bd1\n\n\u003c!-- CONTRIBUTING --\u003e\n\n## Contributing\n\nContributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**.\n\n1. Fork the Project\n2. Create your Feature Branch ( `git checkout -b feature` )\n3. Commit your Changes ( `git commit -m \"Add a cool feature\"` )\n4. Push to the Branch ( `git push origin feature` )\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License - see the [ `LICENSE` ](LICENSE) file for details\n\n\u003c!-- CONTACT --\u003e\n\n## Contact\n\nKarey Higuera - [@kbravh](https://twitter.com/kbravh) - karey.higuera@gmail.com\n\nProject Link: [https://github.com/kbravh/tweet-to-markdown](https://github.com/kbravh/tweet-to-markdown)\n\n\u003c!-- MARKDOWN LINKS --\u003e\n\n[issues-shield]: https://img.shields.io/github/issues/kbravh/tweet-to-markdown.svg?style=flat-square\n[issues-url]: https://github.com/kbravh/tweet-to-markdown/issues\n[license-shield]: https://img.shields.io/github/license/kbravh/tweet-to-markdown.svg?style=flat-square\n[license-url]: https://github.com/kbravh/tweet-to-markdown/blob/master/LICENSE\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square\u0026logo=linkedin\u0026colorB=555\n[linkedin-url]: https://linkedin.com/in/kbravh\n[stars-shield]: https://img.shields.io/github/stars/kbravh/tweet-to-markdown.svg?style=flat-square\n[stars-url]: https://github.com/kbravh/tweet-to-markdown/stargazers\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbravh%2Ftweet-to-markdown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkbravh%2Ftweet-to-markdown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkbravh%2Ftweet-to-markdown/lists"}