diff --git a/docs/traditional-media.md b/docs/traditional-media.md
index 1b0666fade..559f0e7f81 100644
--- a/docs/traditional-media.md
+++ b/docs/traditional-media.md
@@ -1113,6 +1113,18 @@ category 对应的关键词有
+## 客家電視台
+
+### 新聞首頁
+
+
+
+| 客家焦點 | 政經要聞 | 民生醫療 | 地方風采 | 國際萬象 |
+| ----- | --------- | ------- | ----- | ------------- |
+| hakka | political | medical | local | international |
+
+
+
## 理论网
### 学习时报
diff --git a/lib/v2/hakkatv/maintainer.js b/lib/v2/hakkatv/maintainer.js
new file mode 100644
index 0000000000..c0bde2bd1d
--- /dev/null
+++ b/lib/v2/hakkatv/maintainer.js
@@ -0,0 +1,3 @@
+module.exports = {
+ '/news/:type?': ['TonyRL'],
+};
diff --git a/lib/v2/hakkatv/radar.js b/lib/v2/hakkatv/radar.js
new file mode 100644
index 0000000000..8c84b71884
--- /dev/null
+++ b/lib/v2/hakkatv/radar.js
@@ -0,0 +1,13 @@
+module.exports = {
+ 'hakkatv.org.tw': {
+ _name: '客家電視台',
+ '.': [
+ {
+ title: '新聞首頁 - 客家電視台',
+ docs: 'https://docs.rsshub.app/traditional-media.html#ke-jia-dian-shi-tai',
+ source: '/news',
+ target: '/hakkatv/news',
+ },
+ ],
+ },
+};
diff --git a/lib/v2/hakkatv/router.js b/lib/v2/hakkatv/router.js
new file mode 100644
index 0000000000..71d9da1374
--- /dev/null
+++ b/lib/v2/hakkatv/router.js
@@ -0,0 +1,3 @@
+module.exports = (router) => {
+ router.get('/news/:type?', require('./type'));
+};
diff --git a/lib/v2/hakkatv/type.js b/lib/v2/hakkatv/type.js
new file mode 100644
index 0000000000..35d6bd7f61
--- /dev/null
+++ b/lib/v2/hakkatv/type.js
@@ -0,0 +1,67 @@
+const got = require('@/utils/got');
+const { parseDate } = require('@/utils/parse-date');
+const timezone = require('@/utils/timezone');
+
+const typeMap = ['hakka', 'political', 'medical', 'local', 'international'];
+const baseUrl = 'https://www.hakkatv.org.tw';
+const apiUrl = 'https://api.hakkatv.org.tw';
+
+module.exports = async (ctx) => {
+ const { type } = ctx.params;
+
+ let allData;
+ if (!type) {
+ allData = await Promise.all(
+ typeMap.map(async (t) => {
+ const { data } = await got(`${apiUrl}/api/news/index`, {
+ searchParams: {
+ per: 4,
+ 'sort[created_at]': 'desc',
+ type: t,
+ keywords: '',
+ },
+ });
+ return data.data;
+ })
+ );
+ } else {
+ allData = (
+ await got(`${apiUrl}/api/news/index`, {
+ searchParams: {
+ per: 4,
+ 'sort[created_at]': 'desc',
+ type,
+ keywords: '',
+ },
+ })
+ ).data.data;
+ }
+
+ const list = [].concat(...allData).map((item) => ({
+ title: item.title,
+ pubDate: timezone(parseDate(item.created_at), +8),
+ author: item.author,
+ link: `${baseUrl}/news-detail/${item.id}`,
+ id: item.id,
+ }));
+
+ const items = await Promise.all(
+ list.map((item) =>
+ ctx.cache.tryGet(item.link, async () => {
+ const { data } = await got(`${apiUrl}/api/news/read/${item.id}`);
+ item.category = data.tag.map((t) => t.tag);
+ item.description = data.content.replace(/\n/g, '
');
+ delete item.id;
+ return item;
+ })
+ )
+ );
+
+ ctx.state.data = {
+ title: '新聞首頁 - 客家電視台',
+ description: '客家電視是屬於全民、以至於全世界客家族群的頻道,亦是為傳播客家文化而存在,定位為「全體客家族群之媒體」。',
+ link: `${baseUrl}/news`,
+ language: 'zh-TW',
+ item: items,
+ };
+};
diff --git a/lib/v2/peopo/topic.js b/lib/v2/peopo/topic.js
index 9bc17ae0df..e0c84e484a 100644
--- a/lib/v2/peopo/topic.js
+++ b/lib/v2/peopo/topic.js
@@ -40,6 +40,7 @@ module.exports = async (ctx) => {
ctx.state.data = {
title: $('head title').text(),
link: url,
+ language: 'zh-TW',
item: items,
};
};