diff --git a/docs/en/new-media.md b/docs/en/new-media.md
index 17b61c616..4ca86e70e 100644
--- a/docs/en/new-media.md
+++ b/docs/en/new-media.md
@@ -641,6 +641,18 @@ Compared to the official one, this feed:
+## Sensor Tower
+
+### Blog
+
+
+
+| English | Chinese | Japanese | Korean |
+| ------- | ------- | -------- | ------ |
+| | zh-CN | ja | ko |
+
+
+
## Simons Foundation
### Articles
diff --git a/docs/new-media.md b/docs/new-media.md
index 47ae29c56..b435e637a 100644
--- a/docs/new-media.md
+++ b/docs/new-media.md
@@ -1170,6 +1170,18 @@ IPFS 网关有可能失效,那时候换成其他网关。
+## Sensor Tower
+
+### Blog
+
+
+
+| English | Chinese | Japanese | Korean |
+| ------- | ------- | -------- | ------ |
+| | zh-CN | ja | ko |
+
+
+
## Simons Foundation
### 文章
diff --git a/lib/v2/sensortower/blog.js b/lib/v2/sensortower/blog.js
new file mode 100644
index 000000000..167231d2f
--- /dev/null
+++ b/lib/v2/sensortower/blog.js
@@ -0,0 +1,69 @@
+const got = require('@/utils/got');
+const cheerio = require('cheerio');
+const { parseDate } = require('@/utils/parse-date');
+const { art } = require('@/utils/render');
+const path = require('path');
+
+module.exports = async (ctx) => {
+ const language = ctx.params.language ?? '';
+
+ const rootUrl = 'https://sensortower.com';
+ const currentUrl = `${rootUrl}${language ? `/${language}` : ''}/blog`;
+
+ const response = await got({
+ method: 'get',
+ url: currentUrl,
+ });
+
+ const data = response.data.match(/"uri":"(\/blog\/.*?)"/g);
+
+ let items = data.map((item) => ({
+ link: `${rootUrl}${language ? `/${language}` : ''}${item.match(/"(\/blog\/.*?)"/)[1]}`,
+ }));
+
+ items = await Promise.all(
+ items.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const detailResponse = await got({
+ method: 'get',
+ url: item.link,
+ });
+
+ const content = cheerio.load(detailResponse.data);
+ const detail = JSON.parse(`{${detailResponse.data.match(/("title":.*?),"body":/)[1]}}`);
+
+ content('h1').remove();
+ content('h5').parent().remove();
+ content('div[data-testid="Text-embedded-entry-block"]').remove();
+
+ content('img').each(function () {
+ const image = (content(this).attr('srcset') ?? content(this).attr('src')).split('?w=')[0];
+
+ content(this).replaceWith(
+ art(path.join(__dirname, 'templates/description.art'), {
+ image,
+ })
+ );
+ });
+
+ item.title = detail.title;
+ item.author = detail.author.name;
+ item.pubDate = parseDate(detail.pubDate, 'MMMM YYYY');
+ item.category = (detail.tags?.map((t) => t.title) ?? []).concat(detail.category?.map((c) => c.title) ?? []);
+ item.description = art(path.join(__dirname, 'templates/description.art'), {
+ header: content('header[data-csk-entry-type="blog"]').html(),
+ description: content('div[data-csk-entry-type="blog"] div[data-testid="Text-root"]').html(),
+ });
+
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: 'Sensor Tower - Blog',
+ link: currentUrl,
+ item: items,
+ language: language ? language : 'en-US',
+ };
+};
diff --git a/lib/v2/sensortower/maintainer.js b/lib/v2/sensortower/maintainer.js
new file mode 100644
index 000000000..8135e010a
--- /dev/null
+++ b/lib/v2/sensortower/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/blog/:language?': ['nczitzk'],
+};
diff --git a/lib/v2/sensortower/radar.js b/lib/v2/sensortower/radar.js
new file mode 100644
index 000000000..58f4067c0
--- /dev/null
+++ b/lib/v2/sensortower/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'sensortower.com': {
+ _name: 'Sensor Tower',
+ '.': [
+ {
+ title: 'Blog',
+ docs: 'https://docs.rsshub.app/new-media.html#sensor-tower-blog',
+ source: ['/blog', '/zh-CN/blog', '/ja/blog', '/ko/blog', '/'],
+ target: '/sensortower/blog',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/sensortower/router.js b/lib/v2/sensortower/router.js
new file mode 100644
index 000000000..fadb0f6b3
--- /dev/null
+++ b/lib/v2/sensortower/router.js
@@ -0,0 +1,3 @@
+module.exports = function (router) {
+ router.get('/blog/:language?', require('./blog'));
+};
diff --git a/lib/v2/sensortower/templates/description.art b/lib/v2/sensortower/templates/description.art
new file mode 100644
index 000000000..112e33db7
--- /dev/null
+++ b/lib/v2/sensortower/templates/description.art
@@ -0,0 +1,9 @@
+{{ if image }}
+
+{{ /if }}
+{{ if header }}
+{{@ header }}
+{{ /if }}
+{{ if description }}
+{{@ description }}
+{{ /if }}
\ No newline at end of file