diff --git a/docs/en/install/README.md b/docs/en/install/README.md
index 7e6c5192d6..c0cb3f84f0 100644
--- a/docs/en/install/README.md
+++ b/docs/en/install/README.md
@@ -709,6 +709,10 @@ See docs of the specified route and `lib/config.js` for detailed information.
- `NHENTAI_USERNAME`: nhentai username or email
- `NHENTAI_PASSWORD`: nhentai password
+- Pixabay: [Documentation](https://pixabay.com/api/docs/)
+
+ - `PIXABAY_KEY`: Pixabay API key
+
- pixiv: [Registration](https://accounts.pixiv.net/signup)
- `PIXIV_REFRESHTOKEN`: Please refer to [this article](https://gist.github.com/ZipFile/c9ebedb224406f4f11845ab700124362) to get a `refresh_token`
diff --git a/docs/en/picture.md b/docs/en/picture.md
index 2bf7960d99..84d4dcb6ad 100644
--- a/docs/en/picture.md
+++ b/docs/en/picture.md
@@ -298,6 +298,12 @@ For example:
+## Pixabay
+
+### Search
+
+
+
## Rare Historical Photos
### Home
diff --git a/lib/config.js b/lib/config.js
index beed36b5e6..d72641a3ba 100644
--- a/lib/config.js
+++ b/lib/config.js
@@ -222,6 +222,9 @@ const calculateValue = () => {
pianyuan: {
cookie: envs.PIANYUAN_COOKIE,
},
+ pixabay: {
+ key: envs.PIXABAY_KEY,
+ },
pixiv: {
refreshToken: envs.PIXIV_REFRESHTOKEN,
bypassCdn: envs.PIXIV_BYPASS_CDN !== '0' && envs.PIXIV_BYPASS_CDN !== 'false',
diff --git a/lib/v2/pixabay/maintainer.js b/lib/v2/pixabay/maintainer.js
new file mode 100644
index 0000000000..dfd029e519
--- /dev/null
+++ b/lib/v2/pixabay/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/search/:q/:order?': ['TonyRL'],
+};
diff --git a/lib/v2/pixabay/radar.js b/lib/v2/pixabay/radar.js
new file mode 100644
index 0000000000..c0719a93d3
--- /dev/null
+++ b/lib/v2/pixabay/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'pixabay.com': {
+ _name: 'Pixabay',
+ '.': [
+ {
+ title: 'Search',
+ docs: 'https://docs.rsshub.app/en/picture.html#pixabay',
+ source: ['/:searchType/search/:q'],
+ target: '/pixabay/search/:q',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/pixabay/router.js b/lib/v2/pixabay/router.js
new file mode 100644
index 0000000000..185e1f5570
--- /dev/null
+++ b/lib/v2/pixabay/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/search/:q/:order?', require('./search'));
+};
diff --git a/lib/v2/pixabay/search.js b/lib/v2/pixabay/search.js
new file mode 100644
index 0000000000..4c697537cf
--- /dev/null
+++ b/lib/v2/pixabay/search.js
@@ -0,0 +1,50 @@
+const got = require('@/utils/got');
+const config = require('@/config').value;
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const { q, order = 'latest' } = ctx.params;
+ const key = config.pixabay?.key ?? '7329690-bbadad6d872ba577d5a358679';
+ const baseUrl = 'https://pixabay.com';
+
+ const data = await ctx.cache.tryGet(
+ `pixabay:search:${q}:${order}`,
+ async () => {
+ const { data } = await got(`${baseUrl}/api/`, {
+ searchParams: {
+ key,
+ q,
+ order,
+ per_page: ctx.query.limit ?? 200,
+ },
+ });
+ return data;
+ },
+ Math.max(config.cache.contentExpire, 24 * 60 * 60), // required by Pixabay API
+ false
+ );
+
+ const items = data.hits.map((item) => {
+ const { pageURL, tags, user } = item;
+ return {
+ title: pageURL
+ .substring(pageURL.lastIndexOf('/', pageURL.lastIndexOf('/') - 1) + 1, pageURL.lastIndexOf('/'))
+ .replace(/(-\d+)$/, '')
+ .replace(/-/g, ' '),
+ description: art(path.join(__dirname, 'templates/img.art'), { item }),
+ link: pageURL,
+ category: tags.split(', '),
+ author: user,
+ };
+ });
+
+ ctx.state.data = {
+ title: `Search ${q} - Pixabay`,
+ description: 'Download & use free nature stock photos in high resolution ✓ New free images everyday ✓ HD to 4K ✓ Best nature pictures for all devices on Pixabay',
+ link: `${baseUrl}/images/search/${q}/${order === 'latest' ? '?order=latest' : ''}`,
+ image: `https://pixabay.com/apple-touch-icon.png`,
+ language: 'en',
+ item: items,
+ };
+};
diff --git a/lib/v2/pixabay/templates/img.art b/lib/v2/pixabay/templates/img.art
new file mode 100644
index 0000000000..6ad14ac3e7
--- /dev/null
+++ b/lib/v2/pixabay/templates/img.art
@@ -0,0 +1 @@
+