入門
NIP-36 敏感內容
Nostr 敏感內容標記機制,用於標示需要警告的內容。
5 分鐘
概述
NIP-36 定義了敏感內容標記機制,讓發布者可以為可能令人不適的內容添加警告。 這類似於其他平台的「內容警告」(Content Warning)或「不適合工作場所」(NSFW)標記。 客戶端應該在顯示標記內容前要求用戶確認。
Content-Warning 標籤
使用 content-warning 標籤標記敏感內容,可選擇性地附帶原因說明:
{`["content-warning", "<警告原因>"]`} 事件範例
{`{
"kind": 1,
"tags": [
["content-warning", "暴力內容"]
],
"content": "這則貼文包含可能令人不適的內容...",
...
}`} 無原因的警告
如果不想說明具體原因,可以留空:
{`{
"kind": 1,
"tags": [
["content-warning", ""]
],
"content": "敏感內容...",
...
}`} 實作
建立敏感內容事件
{`import { finalizeEvent } from 'nostr-tools';
// 建立帶有內容警告的事件
function createSensitiveEvent(
privateKey: Uint8Array,
content: string,
warningReason?: string
) {
const event = {
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [
['content-warning', warningReason || ''],
],
content,
};
return finalizeEvent(event, privateKey);
}
// 使用範例
const nsfwPost = createSensitiveEvent(
privateKey,
'這是一則包含敏感圖片的貼文...',
'NSFW 圖片'
);
const spoilerPost = createSensitiveEvent(
privateKey,
'電影結局是...',
'劇透警告'
);
const triggerPost = createSensitiveEvent(
privateKey,
'討論心理健康議題...',
'可能引發不適'
);`} 檢查敏感內容
{`interface ContentWarning {
hasSensitiveContent: boolean;
reason: string | null;
}
// 檢查事件是否有敏感內容標記
function checkContentWarning(event: Event): ContentWarning {
const cwTag = event.tags.find(t => t[0] === 'content-warning');
if (!cwTag) {
return { hasSensitiveContent: false, reason: null };
}
return {
hasSensitiveContent: true,
reason: cwTag[1] || null,
};
}
// 使用範例
const { hasSensitiveContent, reason } = checkContentWarning(event);
if (hasSensitiveContent) {
console.log(\`此內容已標記為敏感\${reason ? \`: \${reason}\` : ''}\`);
}`} 過濾敏感內容
{`// 過濾掉所有敏感內容
function filterSensitiveContent(events: Event[]): Event[] {
return events.filter(event => {
const { hasSensitiveContent } = checkContentWarning(event);
return !hasSensitiveContent;
});
}
// 只保留敏感內容
function getSensitiveContent(events: Event[]): Event[] {
return events.filter(event => {
const { hasSensitiveContent } = checkContentWarning(event);
return hasSensitiveContent;
});
}
// 按敏感程度分類
function categorizeContent(events: Event[]): {
safe: Event[];
sensitive: Event[];
} {
const safe: Event[] = [];
const sensitive: Event[] = [];
for (const event of events) {
const { hasSensitiveContent } = checkContentWarning(event);
if (hasSensitiveContent) {
sensitive.push(event);
} else {
safe.push(event);
}
}
return { safe, sensitive };
}`} UI 顯示建議
客戶端應該:
- 預設隱藏敏感內容
- 顯示警告訊息和原因(如有)
- 提供「顯示內容」按鈕
- 允許用戶設定偏好(總是隱藏、總是顯示等)
{`// React 組件範例
function SensitiveNote({ event }: { event: Event }) {
const [revealed, setRevealed] = useState(false);
const { hasSensitiveContent, reason } = checkContentWarning(event);
// 如果沒有敏感標記,直接顯示
if (!hasSensitiveContent) {
return ;
}
// 顯示警告覆蓋層
if (!revealed) {
return (
⚠️
{reason ? \`敏感內容:\${reason}\` : '此內容已被標記為敏感'}
);
}
// 已確認顯示
return (
⚠️ {reason || '敏感內容'}
);
}`} 用戶偏好設定
{`// 用戶敏感內容偏好
type SensitiveContentPreference =
| 'always_hide' // 總是隱藏
| 'show_warning' // 顯示警告(預設)
| 'always_show'; // 總是顯示
interface UserSettings {
sensitiveContent: SensitiveContentPreference;
}
// 根據用戶設定決定顯示方式
function shouldShowContent(
event: Event,
settings: UserSettings
): { show: boolean; showWarning: boolean } {
const { hasSensitiveContent } = checkContentWarning(event);
if (!hasSensitiveContent) {
return { show: true, showWarning: false };
}
switch (settings.sensitiveContent) {
case 'always_hide':
return { show: false, showWarning: false };
case 'always_show':
return { show: true, showWarning: true };
case 'show_warning':
default:
return { show: false, showWarning: true };
}
}`} 常見警告原因
一些常用的警告原因標籤:
| 原因 | 說明 |
|---|---|
| NSFW | 不適合工作場所的內容 |
| nudity | 裸露內容 |
| violence | 暴力內容 |
| spoiler | 劇透內容 |
| sensitive | 一般敏感內容 |
媒體內容處理
對於包含媒體的敏感內容,建議額外處理:
{`// 敏感媒體處理
function processSensitiveMedia(event: Event): {
content: string;
mediaUrls: string[];
blurMedia: boolean;
} {
const { hasSensitiveContent } = checkContentWarning(event);
// 提取媒體 URL
const mediaUrls = extractMediaUrls(event.content);
return {
content: event.content,
mediaUrls,
blurMedia: hasSensitiveContent,
};
}
// 在 CSS 中模糊處理
const styles = \`
.blurred-media {
filter: blur(20px);
transition: filter 0.3s ease;
}
.blurred-media:hover,
.blurred-media.revealed {
filter: none;
}
\`;`} 中繼器處理
中繼器可以根據自己的政策處理敏感內容:
- 接受所有內容(預設)
- 拒絕有敏感標記的內容
- 僅接受有敏感標記的成人內容
最佳實踐
發布者應該誠實標記敏感內容,這有助於建立健康的社群環境。 客戶端則應尊重這些標記,讓用戶自行決定是否查看。
注意事項
- 自願性:標記是發布者自願的,無法強制執行
- 主觀性:「敏感」的定義因人而異
- 回覆內容:回覆敏感貼文不會自動繼承敏感標記
- 轉發處理:轉發時應保留原始的敏感標記
相關 NIP
參考資源
已複製連結