[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-72096":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":35,"readmeContent":36,"aiSummary":37,"trendingCount":16,"starSnapshotCount":16,"syncStatus":38,"lastSyncTime":39,"discoverSource":40},72096,"zotero-arxiv-daily","TideDra\u002Fzotero-arxiv-daily","TideDra","Recommend new arxiv papers of your interest daily according to your Zotero libarary.","",null,"Python",5500,4845,37,45,0,40,89,226,120,41,"GNU Affero General Public License v3.0",false,"main",true,[27,28,29,30,31,32,33,34],"arxiv","automation","e-mail","github-action","paper","recommendation","research","zotero","2026-06-12 02:02:58","\u003Cp align=\"center\">\n  \u003Ca href=\"\" rel=\"noopener\">\n \u003Cimg width=200px height=200px src=\"assets\u002Flogo.svg\" alt=\"logo\">\u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Ch3 align=\"center\">Zotero-arXiv-Daily\u003C\u002Fh3>\n\n\u003Cdiv align=\"center\">\n\n  [![Status](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fstatus-active-success.svg)]()\n  ![Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002FTideDra\u002Fzotero-arxiv-daily?style=flat)\n  [![GitHub Issues](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fissues\u002FTideDra\u002Fzotero-arxiv-daily)](https:\u002F\u002Fgithub.com\u002FTideDra\u002Fzotero-arxiv-daily\u002Fissues)\n  [![GitHub Pull Requests](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fissues-pr\u002FTideDra\u002Fzotero-arxiv-daily)](https:\u002F\u002Fgithub.com\u002FTideDra\u002Fzotero-arxiv-daily\u002Fpulls)\n  [![License](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002FTideDra\u002Fzotero-arxiv-daily)](\u002FLICENSE)\n  [\u003Cimg src=\"https:\u002F\u002Fapi.gitsponsors.com\u002Fapi\u002Fbadge\u002Fimg?id=893025857\" height=\"20\">](https:\u002F\u002Fapi.gitsponsors.com\u002Fapi\u002Fbadge\u002Flink?p=PKMtRut1dWWuC1oFdJweyDSvJg454\u002FGkdIx4IinvBblaX2AY4rQ7FYKAK1ZjApoiNhYEeduIEhfeZVIwoIVlvcwdJXVFD2nV2EE5j6lYXaT\u002FRHrcsQbFl3aKe1F3hliP26OMayXOoZVDidl05wj+yg==)\n\n\u003C\u002Fdiv>\n\n---\n\n\u003Cp align=\"center\"> Recommend new arxiv papers of your interest daily according to your Zotero library.\n    \u003Cbr> \n\u003C\u002Fp>\n\n> [!IMPORTANT]\n> Please keep an eye on this repo, and merge your forked repo in time when there is any update of this upstream, in order to enjoy new features and fix found bugs.\n\n## 🧐 About \u003Ca name = \"about\">\u003C\u002Fa>\n\n> Track new scientific researches of your interest by just forking (and staring) this repo!😊\n\n*Zotero-arXiv-Daily* finds arxiv papers that may attract you based on the context of your Zotero library, and then sends the result to your mailbox📮. It can be deployed as Github Action Workflow with **zero cost**, **no installation**, and **few configuration** of Github Action environment variables for daily **automatic** delivery.\n\n## ✨ Features\n- Totally free! All the calculation can be done in the Github Action runner locally within its quota (for public repo).\n- AI-generated TL;DR for you to quickly pick up target papers.\n- Affiliations of the paper are resolved and presented.\n- Links of PDF and code implementation (if any) presented in the e-mail.\n- List of papers sorted by relevance with your recent research interest.\n- Fast deployment via fork this repo and set environment variables in the Github Action Page.\n- Support LLM API for generating TL;DR of papers.\n- Ignore unwanted Zotero papers using a list of glob patterns.\n- Support multiple sources of papers to retrieve:\n  - arxiv\n  - biorxiv\n  - medrxiv\n\n## 📷 Screenshot\n![screenshot](.\u002Fassets\u002Fscreenshot.png)\n\n## 🚀 Usage\n### Quick Start\n1. Fork (and star😘) this repo.\n![fork](.\u002Fassets\u002Ffork.png)\n\n2. Set Github Action environment variables.\n![secrets](.\u002Fassets\u002Fsecrets.png)\n\nBelow are all the secrets you need to set. They are invisible to anyone including you once they are set, for security.\n\n| Key |Description | Example |\n| :---  | :---  | :--- |\n| ZOTERO_ID  | User ID of your Zotero account. **User ID is not your username, but a sequence of numbers**Get your ID from [here](https:\u002F\u002Fwww.zotero.org\u002Fsettings\u002Fsecurity). You can find it at the position shown in this [screenshot](https:\u002F\u002Fgithub.com\u002FTideDra\u002Fzotero-arxiv-daily\u002Fblob\u002Fmain\u002Fassets\u002Fuserid.png). | 12345678  |\n| ZOTERO_KEY | An Zotero API key with read access. Get a key from [here](https:\u002F\u002Fwww.zotero.org\u002Fsettings\u002Fsecurity).  | AB5tZ877P2j7Sm2Mragq041H   |\n| SENDER | The email account of the SMTP server that sends you email. | abc@qq.com |\n| SENDER_PASSWORD | The password of the sender account. Note that it's not necessarily the password for logging in the e-mail client, but the authentication code for SMTP service. Ask your email provider for this.   | abcdefghijklmn |\n| RECEIVER | The e-mail address that receives the paper list. | abc@outlook.com |\n| OPENAI_API_KEY | API Key when using the API to access LLMs. You can get FREE API for using advanced open source LLMs in [SiliconFlow](https:\u002F\u002Fcloud.siliconflow.cn\u002Fi\u002Fb3XhBRAm). | sk-xxx |\n| OPENAI_API_BASE | API URL when using the API to access LLMs. | https:\u002F\u002Fapi.siliconflow.cn\u002Fv1 |\n\nThen you should also set a public variable `CUSTOM_CONFIG` for your custom configuration.\n![vars](.\u002Fassets\u002Frepo_var.png)\n![custom_config](.\u002Fassets\u002Fconfig_var.png)\nPaste the following content into the value of `CUSTOM_CONFIG` variable:\n```yaml\nzotero:\n  user_id: ${oc.env:ZOTERO_ID}\n  api_key: ${oc.env:ZOTERO_KEY}\n  include_path: null # Or e.g. [\"2026\u002Fsurvey\u002F**\", \"2026\u002Freading-group\u002F**\"]\n\nemail:\n  sender: ${oc.env:SENDER}\n  receiver: ${oc.env:RECEIVER}\n  smtp_server: smtp.qq.com\n  smtp_port: 465\n  sender_password: ${oc.env:SENDER_PASSWORD}\n\nllm:\n  api:\n    key: ${oc.env:OPENAI_API_KEY}\n    base_url: ${oc.env:OPENAI_API_BASE}\n  generation_kwargs:\n    model: gpt-4o-mini\n\nsource:\n  arxiv:\n    category: [\"cs.AI\",\"cs.CV\",\"cs.LG\",\"cs.CL\"]\n    include_cross_list: false # Set to true to include arXiv cross-list papers in these categories.\n\nexecutor:\n  debug: ${oc.env:DEBUG,null}\n  source: ['arxiv']\n```\nSet `source.arxiv.include_cross_list: true` if you want cross-listed papers included.\n>[!NOTE]\n> `${oc.env:XXX,yyy}` means the value of the environment variable `XXX`. If the variable is not set, the default value `yyy` will be used.\n\nHere is the full configuration, `???` means the value must be filled in:\n```yaml\nzotero:\n  user_id: ??? # User ID of your Zotero account.\n  api_key: ??? # An Zotero API key with read access.\n  include_path: null # A list of glob patterns marking the Zotero collections that should be included. Example: [\"2026\u002Fsurvey\u002F**\", \"2026\u002Freading-group\u002F**\"]\n\nsource:\n  arxiv:\n    category: null # The categories of target arxiv papers. Find the abbr of your research area from [here](https:\u002F\u002Farxiv.org\u002Fcategory_taxonomy). Example: [\"cs.AI\",\"cs.CV\",\"cs.LG\",\"cs.CL\"]\n    include_cross_list: false # Whether to include arXiv cross-list papers in subscribed categories. Example: true\n  biorxiv:\n    category: null # The categories of target biorxiv papers. Find categories from [here](https:\u002F\u002Fwww.biorxiv.org\u002F). Example: [\"biochemistry\",\"animal behavior and cognition\"]\n  medrxiv:\n    category: null # The categories of target medrxiv papers. Find categories from [here](https:\u002F\u002Fwww.medrxiv.org\u002F) Example: [\"psychiatry and clinical psychology\", \"neurology\"]\n\nemail:\n  sender: ??? # The email account of the SMTP server that sends you email. Example: abc@qq.com\n  receiver: ??? # The email account that receives the paper list. Example: abc@outlook.com\n  smtp_server: ??? # The SMTP server that sends the email. Ask your email provider (Gmail, QQ, Outlook, ...) for its SMTP server. Example: smtp.qq.com\n  smtp_port: ??? # The port of SMTP server. Example: 465\n  sender_password: ??? # The password of the sender account. Note that it's not necessarily the password for logging in the e-mail client, but the authentication code for SMTP service. Ask your email provider for this. Example: abcdefghijklmn\n\nllm:\n  api:\n    key: ??? # API Key of your LLM API. Example: sk-xxx\n    base_url: ??? # API URL of your LLM API. Example: https:\u002F\u002Fapi.openai.com\u002Fv1\n  generation_kwargs:\n  # Arguments for the LLM API. See [here](https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fapi-reference\u002Fchat\u002Fcreate) for more details.\n    max_tokens: 16384\n    model: ???\n  language: English # Preferred language for the TL;DR. Example: English\n\nreranker:\n  local:\n    model: jinaai\u002Fjina-embeddings-v5-text-nano # The Hugging Face model name of the local embedding model. Example: jinaai\u002Fjina-embeddings-v5-text-nano\n    encode_kwargs:\n    # The kwargs for the encode method of the local embedding model. Details see [here](https:\u002F\u002Fwww.sbert.net\u002Fdocs\u002Fpackage_reference\u002FSentenceTransformer.html#sentence_transformers.SentenceTransformer.encode)\n      task: retrieval\n      prompt_name: document\n  api:\n    key: null # API Key of your embedding model API. Example: sk-xxx\n    base_url: null # API URL of your embedding model API. Example: https:\u002F\u002Fapi.openai.com\u002Fv1\n    model: null # The model name of the embedding model. Example: text-embedding-3-large\n    batch_size: null # The batch size for embedding API requests. Adjust to match your provider's limit. Example: 64\n\nexecutor:\n  debug: false # Whether to use debug mode. Example: true\n  send_empty: false # Whether to send an empty email even if no new papers today. Example: true\n  max_paper_num: 100 # The maximum number of the papers presented in the email. Example: 100\n  source: ??? # The sources of papers to retrieve. Example: ['arxiv','biorxiv','medrxiv']\n  reranker: local # The reranker to use. Example: 'local' or 'api'\n```\n\nThat's all! Now you can test the workflow by manually triggering it:\n![test](.\u002Fassets\u002Ftest.png)\n\n> [!NOTE]\n> The Test-Workflow Action is the debug version of the main workflow (Send-emails-daily), which always retrieve 5 arxiv papers regardless of the date. While the main workflow will be automatically triggered everyday and retrieve new papers released yesterday. There is no new arxiv paper at weekends and holiday, in which case you may see \"No new papers found\" in the log of main workflow.\n\nThen check the log and the receiver email after it finishes.\n\nBy default, the main workflow runs on 22:00 UTC everyday. You can change this time by editting the workflow config `.github\u002Fworkflows\u002Fmain.yml`.\n\n### Local Running\nSupported by [uv](https:\u002F\u002Fgithub.com\u002Fastral-sh\u002Fuv), this workflow can easily run on your local device if uv is installed:\n```bash\n# set all the environment variables\n# export ZOTERO_ID=xxxx\n# ...\ncd zotero-arxiv-daily\nuv run main.py\n```\n\n## 🚀 Sync with the latest version\nThis project is in active development. You can subscribe this repo via `Watch` so that you can be notified once we publish new release.\n\n![Watch](.\u002Fassets\u002Fsubscribe_release.png)\n\n\n## 📖 How it works\n*Zotero-arXiv-Daily* firstly retrieves all the papers in your Zotero library and all the papers released in the previous day, via corresponding API. Then it calculates the embedding of each paper's abstract via an embedding model. The score of a paper is its weighted average similarity over all your Zotero papers (newer paper added to the library has higher weight). The TLDR of each paper is generated by LLM, given the text extracted by pymupdf4llm.\n\n## 📌 Limitations\n- The recommendation algorithm is very simple, it may not accurately reflect your interest. Welcome better ideas for improving the algorithm!\n- High `MAX_PAPER_NUM` can lead the execution time exceed the limitation of Github Action runner (6h per execution for public repo, and 2000 mins per month for private repo). Commonly, the quota given to public repo is definitely enough for individual use. If you have special requirements, you can deploy the workflow in your own server, or use a self-hosted Github Action runner, or pay for the exceeded execution time.\n\n\n## 📃 License\nDistributed under the AGPLv3 License. See `LICENSE` for detail.\n\n## ❤️ Acknowledgement\n- [pyzotero](https:\u002F\u002Fgithub.com\u002Furschrei\u002Fpyzotero)\n- [arxiv](https:\u002F\u002Fgithub.com\u002Flukasschwab\u002Farxiv.py)\n- [sentence_transformers](https:\u002F\u002Fgithub.com\u002FUKPLab\u002Fsentence-transformers)\n\n## ☕ Buy Me A Coffee\nIf you find this project helpful, welcome to sponsor me via WeChat or via [ko-fi](https:\u002F\u002Fko-fi.com\u002Ftidedra).\n![wechat_qr](assets\u002Fwechat_sponsor.JPG)\n\n\n## 🌟 Star History\n\n[![Star History Chart](https:\u002F\u002Fapi.star-history.com\u002Fsvg?repos=TideDra\u002Fzotero-arxiv-daily&type=Date)](https:\u002F\u002Fstar-history.com\u002F#TideDra\u002Fzotero-arxiv-daily&Date)\n","Zotero-arXiv-Daily 项目根据用户的 Zotero 图书馆推荐每日新发布的 arXiv 论文。该项目使用 Python 编写，通过分析用户在 Zotero 中已有的文献来推断其研究兴趣，并据此从 arXiv、bioRxiv 和 medRxiv 等来源中筛选出相关的新论文，然后将结果自动发送到用户的邮箱。它支持零成本部署于 GitHub Actions 上，无需额外安装软件，只需简单配置环境变量即可实现自动化运行。此外，还提供了AI生成的摘要、作者机构解析等功能，帮助研究人员高效地跟踪领域内的最新进展。非常适合需要持续关注特定科研领域动态的研究人员使用。",2,"2026-06-11 03:40:21","high_star"]