feat: restore AdSense support, and say so on the privacy page (#3800)

* feat: restore AdSense support, and say so on the privacy page

Same story as dsh-market: an ad placement was merged in August (#2519,
#2525) and lost when main was rewritten. This re-lands the AdSense half.

Not a straight revert. The original carried EthicalAds as a second,
mutually exclusive network; that application was never actually submitted
and EA_PUBLISHER never held a value, so the slot markup, the .adband/.adslot
CSS in both templates and the two-network exclusion check are dropped. What
remains is one head tag — Auto ads place their own units.

ADSENSE_CLIENT unset emits nothing. Verified by diffing a full 5370-page
build against the pre-change output: identical except the privacy pages.

ads.txt goes in site/assets/, which is copied flat into the output root
(the same path CNAME and robots.txt take) so it is served from /ads.txt.
AdSense verifies domain ownership from it, so it ships unconditionally,
before the review rather than after.

The privacy page said there were no ads and no arrangement to introduce
any. Both languages now describe what runs, and the two "no cookies"
claims are corrected — AdSense sets them, and disclosing that is a
condition of running AdSense at all. The PRIVACY_DESC meta strings in
locales.mjs said the same thing and are updated with them. The privacy
template gets no ad token: the page describing what the site loads does
not itself load an ad.

* fix: point dshmobile's screenshots at the entry URL it actually has

#3304 moved the dshmobile entry from `/tree/main/plugins/dshmobile-plugin`
to `/tree/main/plugins` in the README but left data/screenshots.json keyed
on the old path. The build requires every screenshots.json key to match a
listed entry link exactly, so it has been throwing since:

  data/screenshots.json: ".../plugins/dshmobile-plugin" is not a listed
  entry URL (keys must match the README entry link exactly)

That is a hard exit, so "Build site from README" has failed on every push
to main since — the live site has not been redeploying, and pr-check fails
for contributors whose submissions have nothing to do with it.

Same four images, same repository; only the key's subdirectory was stale.
This commit is contained in:
fkysly
2026-08-30 13:06:20 +08:00
committed by GitHub
parent 768490a008
commit 95f1e8d67e
9 changed files with 45 additions and 15 deletions
+5
View File
@@ -109,6 +109,11 @@ jobs:
# npm can never be stuck on a stale "not published" (see #487).
# Push-triggered runs stay incremental.
PROBE_ALL: ${{ (github.event_name == 'schedule' || inputs.probe_all) && '1' || '' }}
# Unset until the AdSense review clears this domain; while unset the
# build emits no ad markup and no third-party script, so the site is
# byte-identical to an ad-free one. A variable rather than a secret:
# the publisher id ships in the HTML either way.
ADSENSE_CLIENT: ${{ vars.ADSENSE_CLIENT }}
run: |
# Probing is for the nightly run and manual dispatch only. A push
# build deploys what is already committed or cached; it does not go
+1 -1
View File
@@ -963,7 +963,7 @@
"https://raw.githubusercontent.com/yyyyukari/dsh-plugin-workshop/master/assets/installed-view.jpg",
"https://raw.githubusercontent.com/yyyyukari/dsh-plugin-workshop/master/assets/sidebar-entry.jpg"
],
"https://github.com/zdx8637-gitdog/dshmobile/tree/main/plugins/dshmobile-plugin": [
"https://github.com/zdx8637-gitdog/dshmobile/tree/main/plugins": [
"https://raw.githubusercontent.com/zdx8637-gitdog/dshmobile/main/docs/images/plugin-panel.jpg",
"https://raw.githubusercontent.com/zdx8637-gitdog/dshmobile/main/docs/images/phone-1.jpg",
"https://raw.githubusercontent.com/zdx8637-gitdog/dshmobile/main/docs/images/phone-2.jpg",
+22
View File
@@ -54,6 +54,25 @@ const CAT_IDS = ENTRY_CAT_IDS
const ldSafe = (s) => s.replaceAll('<', '\\u003c')
const esc = (s) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
// ── advertising ─────────────────────────────────────────────────────────────
// One AdSense head tag, gated behind a build variable. Unset — the default —
// emits nothing at all, so an unconfigured build is byte-identical to an
// ad-free one and no third-party script is requested.
//
// Auto ads decide placement from this tag alone, so there is no slot markup to
// write and no reserved height to get wrong. The publisher id is a `vars`
// entry rather than a secret because it ships in the HTML either way.
const ADSENSE_CLIENT = process.env.ADSENSE_CLIENT || ''
const adHead = () =>
ADSENSE_CLIENT
? `<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${esc(ADSENSE_CLIENT)}" crossorigin="anonymous"></script>\n`
: ''
// The token sits on its own line in every template, so the match takes the
// newline with it. Otherwise an unconfigured build leaves a blank line behind
// and "identical to an ad-free build" stops being literally true — which is
// the one claim about this feature worth being able to check by diffing.
const AD_HEAD_TOKEN = '__AD_HEAD__\n'
// Comments are deliberately opt-in. A half-configured widget would otherwise
// turn every detail page into a broken third-party request, so fail loudly only
// when a maintainer says it is ready to ship.
@@ -465,6 +484,7 @@ for (const loc of LOCALES) {
.replaceAll('__PRIVACY__', () => loc.privacyPath)
.replaceAll('__LANG_REDIRECT__', () => langRedirect(loc))
.replaceAll('__FEED__', () => loc.feed)
.replaceAll(AD_HEAD_TOKEN, () => adHead())
for (const [k, v] of Object.entries(loc.strings)) page = page.replaceAll(`__T_${k}__`, () => v)
fs.mkdirSync(loc.out.split('/').slice(0, -1).join('/'), { recursive: true })
fs.writeFileSync(loc.out, page)
@@ -508,6 +528,7 @@ for (const loc of LOCALES) {
.replaceAll('__PRIVACY__', () => loc.privacyPath)
.replaceAll('__LANG_REDIRECT__', () => '')
.replaceAll('__FEED__', () => loc.feed)
.replaceAll(AD_HEAD_TOKEN, () => adHead())
for (const [k, v] of Object.entries(loc.strings)) page = page.replaceAll(`__T_${k}__`, () => v)
const outDir = loc.out.replace(/index\.html$/, '') + id
fs.mkdirSync(outDir, { recursive: true })
@@ -763,6 +784,7 @@ ${readmeHtml}
.replaceAll('__PRIVACY__', () => loc.privacyPath)
.replaceAll('__LOCALE_LINKS__', () => LOCALES.filter((l) => l.code !== loc.code).map((l) => `<a class="lang-btn" href="${l.urlPath}p/${e.slug}/" hreflang="${l.code}" rel="alternate">${l.label}</a>`).join('\n '))
.replaceAll('__CAT_URL__', () => catUrl)
.replaceAll(AD_HEAD_TOKEN, () => adHead())
.replaceAll('__CAT_NAME__', () => loc.categories[e.cat])
.replaceAll('__P_SHORT__', () => esc(short))
.replaceAll('__P_H1__', () => h1)
+1
View File
@@ -0,0 +1 @@
google.com, pub-8176276536851769, DIRECT, f08c47fec0942fa0
+1
View File
@@ -163,6 +163,7 @@ footer p+p{margin-top:.5rem}
.cmd button{border-left:none;border-top:1px solid var(--line-2);padding:.5rem}
}
</style>
__AD_HEAD__
</head>
<body>
+2 -2
View File
@@ -29,7 +29,7 @@ export default [
privacyPath: '/privacy/',
privacyBody: 'site/privacy.en.html',
PRIVACY_TITLE: 'Privacy — Awesome DSH Plugin',
PRIVACY_DESC: 'What this site collects and what it does not: no cookies, no browser storage, cookie-less analytics, and optional GitHub-hosted community comments.',
PRIVACY_DESC: 'What this site collects and what it does not: no browser storage, cookie-less analytics, Google ads, and optional GitHub-hosted community comments.',
TITLE: 'Awesome DSH Plugin — Curated DeepSeek Harness (dsh) Plugin List',
DESC: 'A curated list of {N} DeepSeek Harness (dsh) plugins: UI, themes, sessions, memory, tools, workflow, notifications, models, development, and fun. Updated continuously.',
SEARCH_PH: 'Search plugins…',
@@ -165,7 +165,7 @@ export default [
privacyPath: '/zh/privacy/',
privacyBody: 'site/privacy.zh.html',
PRIVACY_TITLE: '隐私政策 — Awesome DSH Plugin',
PRIVACY_DESC: '本站收集什么、不收集什么:不设 cookie、不写浏览器存储、统计不依赖 cookie,以及由用户主动加载的 GitHub 社区评论。',
PRIVACY_DESC: '本站收集什么、不收集什么:不写浏览器存储、统计不依赖 cookie、Google 广告,以及由用户主动加载的 GitHub 社区评论。',
TITLE: 'Awesome DSH Plugin — DeepSeek Harness(dsh)插件精选列表',
DESC: 'DeepSeek Harness(dsh)插件精选列表,收录 {N} 个:UI 增强、主题外观、会话记忆、工具、工作流、通知集成、模型接入、开发与娱乐,持续更新。',
SEARCH_PH: '搜索插件…',
+6 -6
View File
@@ -1,17 +1,17 @@
<h1>Privacy</h1>
<p class="updated">Last updated 2026-08-27. This page is written from the code, not from intent — every claim below is checkable in <a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin" rel="noopener">the repository</a> that builds this site. If something here does not match what the site does, that is a bug and we want to hear about it.</p>
<p class="updated">Last updated 2026-08-30. This page is written from the code, not from intent — every claim below is checkable in <a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin" rel="noopener">the repository</a> that builds this site. If something here does not match what the site does, that is a bug and we want to hear about it.</p>
<h2>The short version</h2>
<p>This is a static site with no accounts and no server we operate. It sets <strong>no cookies</strong> and stores nothing in your browser. It counts page views without identifying you. Apart from that counter, no third party is contacted to render a page unless you scroll down to its community comments.</p>
<p>This is a static site with no accounts and no server we operate. It counts page views without identifying you and stores nothing of its own in your browser. It carries <a href="#advertising">Google ads</a>, which do use cookies.</p>
<h2>Analytics</h2>
<p>We use <strong>Cloudflare Web Analytics</strong>. It is cookie-less, does not fingerprint you, and does not follow you across sites. It records page views and coarse technical facts — referrer, country, browser and device class — which Cloudflare aggregates. We see counts, never individuals, and there is no way for us to single you out from them. See <a href="https://www.cloudflare.com/web-analytics/" rel="noopener">Cloudflare Web Analytics</a>.</p>
<h2>Cookies and browser storage</h2>
<p>This site sets no cookies. It writes nothing to <code>localStorage</code> or <code>sessionStorage</code>. Your filter, sort and search state lives in the URL, which never leaves your browser unless you copy the link yourself.</p>
<p>This site sets none of its own; Google sets cookies for the ads — see <a href="#advertising">Advertising</a>. It writes nothing to <code>localStorage</code> or <code>sessionStorage</code>. Your filter, sort and search state lives in the URL, which never leaves your browser unless you copy the link yourself.</p>
<h2>What a page loads</h2>
<p>Fonts and stylesheets are served from this domain — there are no third-party webfonts. There are no ad networks, no social widgets, no tag managers, and no scripts beyond the analytics counter named above and the small amount of filtering code in the page itself. The optional comments client is not present or requested until you scroll its panel near the viewport; a page you open without scrolling down to the comments contacts no third party for them.</p>
<p>Fonts and stylesheets are served from this domain — there are no third-party webfonts. There are no social widgets, no tag managers, and no scripts beyond the analytics counter named above, the ad script described below, and the small amount of filtering code in the page itself. The optional comments client is not present or requested until you scroll its panel near the viewport; a page you open without scrolling down to the comments contacts no third party for them.</p>
<h2>Community comments</h2>
<p>Plugin detail pages can offer comments through <strong>Giscus</strong>, an open-source widget backed by GitHub Discussions. If you choose to load comments, your browser contacts <code>giscus.app</code> and GitHub. Comments, reactions, GitHub usernames and timestamps are public in the repository’s GitHub Discussions; you need a GitHub account to post. Giscus and GitHub process that interaction under their own terms and privacy policies. The site does not store a comment copy, and it never loads the widget for visitors who do not scroll to it.</p>
@@ -31,8 +31,8 @@
<h2>Contributing</h2>
<p>Submissions arrive as pull requests on GitHub, under GitHub's terms and with the visibility any public repository has. Nothing is submitted through this website; the optional comments UI writes to GitHub Discussions, not to a form or server we operate.</p>
<h2>Advertising</h2>
<p>There are no ads on this site, and no arrangement to introduce any. If that changes, this page will be updated to describe exactly what runs and what it receives, and the change will be visible in this repository's history.</p>
<h2 id="advertising">Advertising</h2>
<p>This site carries ads from <strong>Google AdSense</strong>, loaded from <code>pagead2.googlesyndication.com</code>. Google sets cookies to serve and measure them and receives your IP address with each ad request. You can change what Google does with your data at <a href="https://myadcenter.google.com/" rel="noopener">My Ad Center</a>.</p>
<h2>Contact</h2>
<p>Corrections and questions: <a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/issues" rel="noopener">open an issue</a>.</p>
+6 -6
View File
@@ -1,17 +1,17 @@
<h1>隐私政策</h1>
<p class="updated">最后更新 2026-08-27。本页按代码写,不按意图写——下面每一条都能在构建本站的<a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin" rel="noopener">仓库</a>里核对。如果哪一条和站点实际行为对不上,那是 bug,请告诉我们。</p>
<p class="updated">最后更新 2026-08-30。本页按代码写,不按意图写——下面每一条都能在构建本站的<a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin" rel="noopener">仓库</a>里核对。如果哪一条和站点实际行为对不上,那是 bug,请告诉我们。</p>
<h2>一句话版本</h2>
<p>这是一个静态站点,没有账号,我们也不运营任何服务器。它<strong>不设置任何 cookie</strong>,不在你的浏览器里存任何东西。它统计页面访问量,但无法识别你是谁。除这个计数器外,渲染页面不会联系任何第三方——除非你向下滚动到社区评论。</p>
<p>这是一个静态站点,没有账号,我们也不运营任何服务器。它统计页面访问量但无法识别你是谁,自身也不在你的浏览器里存任何东西。页面上有 <a href="#advertising">Google 广告</a>,广告会用到 cookie。</p>
<h2>访问统计</h2>
<p>我们使用 <strong>Cloudflare Web Analytics</strong>。它不用 cookie,不做浏览器指纹,也不跨站跟踪你。它记录页面访问量和粗粒度的技术信息——来源页、国家/地区、浏览器与设备类别——由 Cloudflare 聚合。我们看到的是数字,不是个人,也没有任何办法从里面把你单独识别出来。详见 <a href="https://www.cloudflare.com/web-analytics/" rel="noopener">Cloudflare Web Analytics</a>。</p>
<h2>Cookie 与浏览器存储</h2>
<p>本站不设置 cookie,不写入 <code>localStorage</code> 或 <code>sessionStorage</code>。你的筛选、排序和搜索状态保存在 URL 里,除非你自己复制链接,否则它不会离开你的浏览器。</p>
<p>本站自身不设置 cookie;Google 会为广告设置 cookie,见<a href="#advertising">广告</a>一节。本站不写入 <code>localStorage</code> 或 <code>sessionStorage</code>。你的筛选、排序和搜索状态保存在 URL 里,除非你自己复制链接,否则它不会离开你的浏览器。</p>
<h2>一个页面会加载什么</h2>
<p>字体和样式表都由本域名提供,<strong>没有第三方网络字体</strong>。没有广告网络,没有社交组件,没有代码管理器(tag manager),除上面提到的统计脚本和页面内少量筛选逻辑外没有其他脚本。可选的评论客户端在你把评论面板滚动到视口附近之前不会出现在页面中或发起请求;只要你打开页面后没有向下滚动到评论区,页面就不会为此联系任何第三方。</p>
<p>字体和样式表都由本域名提供,<strong>没有第三方网络字体</strong>。没有社交组件,没有代码管理器(tag manager);除上面提到的统计脚本、下文所述的广告脚本,以及页面内少量筛选逻辑外,没有其他脚本。可选的评论客户端在你把评论面板滚动到视口附近之前不会出现在页面中或发起请求;只要你打开页面后没有向下滚动到评论区,页面就不会为此联系任何第三方。</p>
<h2>社区评论</h2>
<p>插件详情页可通过 <strong>Giscus</strong> 提供评论;它是一个由 GitHub Discussions 支撑的开源组件。你选择加载评论后,浏览器会连接 <code>giscus.app</code> 与 GitHub。评论、反应、GitHub 用户名和时间戳会公开保存在本仓库的 GitHub Discussions 中;发表内容需要 GitHub 账号。Giscus 与 GitHub 会依照各自的条款和隐私政策处理这次交互。本站不会保存评论副本,也绝不会为未滚动到评论区的访客请求该组件。</p>
@@ -31,8 +31,8 @@
<h2>参与贡献</h2>
<p>投稿通过 GitHub 的 pull request 提交,适用 GitHub 的条款,并具有公开仓库应有的可见性。本网站不接收任何投稿;可选的评论界面只会写入 GitHub Discussions,不会写入我们运营的表单或服务器。</p>
<h2>广告</h2>
<p>本站没有广告,也没有引入广告的安排。若此事发生变化,本页会更新,明确说明届时运行的是什么、它会收到什么,并且该变更会体现在本仓库的提交历史中。</p>
<h2 id="advertising">广告</h2>
<p>本站有 <strong>Google AdSense</strong> 广告,脚本从 <code>pagead2.googlesyndication.com</code> 加载。Google 会设置 cookie 用于投放和衡量广告,并在每次广告请求中收到你的 IP 地址。你可以在 <a href="https://myadcenter.google.com/" rel="noopener">我的广告中心</a> 更改 Google 对你数据的使用。</p>
<h2>联系方式</h2>
<p>勘误与疑问请<a href="https://github.com/awesome-dsh-plugin/awesome-dsh-plugin/issues" rel="noopener">提交 issue</a>。</p>
+1
View File
@@ -234,6 +234,7 @@ footer .motto{font-family:var(--mono);color:var(--cinnabar)}
.market .go{margin-left:0}
}
</style>
__AD_HEAD__
</head>
<body>
<a class="skip" href="#dex">__T_SKIP__</a>