Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/_deploy-gated.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ on:
description: Github-Environment (Approval-Gate + Secrets)
required: true
type: string
tracking_mode:
description: Piano-Analytics-Site (off | test | production)
required: true
type: string

permissions:
contents: read
Expand Down Expand Up @@ -56,6 +60,7 @@ jobs:
NODE_ENV: production
STAGE: ${{ inputs.stage }}
BRANCH: ${{ github.ref_name }}
TRACKING_MODE: ${{ inputs.tracking_mode }}

- name: CDK-Dependencies installieren
run: npm ci
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ on:
description: GitHub-Environment
required: true
type: string
tracking_mode:
description: Piano-Analytics-Site (off | test | production)
required: true
type: string

permissions:
contents: read
Expand Down Expand Up @@ -57,6 +61,7 @@ jobs:
env:
NODE_ENV: production
STAGE: ${{ inputs.stage }}
TRACKING_MODE: ${{ inputs.tracking_mode }}

# CDK-Projekt (npm). esbuild für das Lambda-Bundling wird aus dem
# Repo-Root (yarn) aufgelöst und muss dort nicht erneut installiert werden
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ jobs:
with:
stage: dev
environment: dev
tracking_mode: test
secrets: inherit
1 change: 1 addition & 0 deletions .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ jobs:
with:
stage: prod
environment: prod
tracking_mode: production
secrets: inherit
1 change: 1 addition & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ jobs:
with:
stage: staging
environment: staging
tracking_mode: test
secrets: inherit
3 changes: 2 additions & 1 deletion src/components/content-wrapper/content-wrapper.css
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
.wrapper p + p,
.wrapper p + h3,
.wrapper p + ul,
.wrapper h3 + p {
.wrapper h3 + p,
.wrapper p + :global(.example) p {
padding-top: 0;
}

Expand Down
13 changes: 13 additions & 0 deletions src/components/piano-opt-out/piano-opt-out.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.opt-out label {
display: inline-flex;
align-items: center;
gap: 0.5rem;
cursor: pointer;
}

.opt-out input {
width: 1.25rem;
height: 1.25rem;
margin: 0;
cursor: pointer;
}
37 changes: 37 additions & 0 deletions src/components/piano-opt-out/piano-opt-out.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { useState } from 'react'

import {
paIsOptedOut,
paSetOptOut,
paTrackingEnabled,
} from '../../lib/piano-analytics/main.js'

import styles from './piano-opt-out.css'

const PianoOptOut = () => {
const [optedOut, setOptedOut] = useState(paIsOptedOut)

if (!paTrackingEnabled) {
return (
<p className={styles.optOut}>
Die Datenerhebung durch Piano Analytics ist derzeit deaktiviert.
</p>
)
}

const onChange = (e) => {
paSetOptOut(e.target.checked)
setOptedOut(paIsOptedOut())
}

return (
<p className={styles.optOut}>
<label>
<input type="checkbox" checked={optedOut} onChange={onChange} />
Der Datenerhebung durch Piano Analytics widersprechen.
</label>
</p>
)
}

export default PianoOptOut
23 changes: 19 additions & 4 deletions src/lib/content/privacy.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
---
title: Datenschutz
imports:
PianoOptOut: '../../components/piano-opt-out/piano-opt-out.jsx'
---

## So gehen wir mit Ihren Daten um
Expand Down Expand Up @@ -33,10 +35,23 @@ Der WDR wird Ihre Daten nur an Dritte weitergeben:

Zu statistischen Zwecken werden sogenannte Zählpixel eingesetzt, die Daten in anonymisierter Form zu Optimierungs- und Studienzwecken sammeln und speichern. Aus diesen Daten werden nicht personenbezogene Auswertungen zur Nutzung unserer Internetangebote erstellt. Die Daten werden nicht dazu genutzt, den Besucher unserer Website persönlich zu identifizieren und sie werden nicht mit anderen Daten zusammengeführt. Diese Messung wurde unter Beachtung des Datenschutzes entwickelt. Ihre Identität bleibt immer geschützt. Sie erhalten über das System keine Werbung.

### Analyse zur Optimierung durch Webtrekk
Darüber hinaus werden bei diesem Verfahren sogenannte "permanente Cookies" eingesetzt. Diese Cookies werden in Form von Textdateien im Browser des Besuchers der Website gespeichert. Sie ermöglichen die Erkennung eines Nutzers bei einem wiederholten Besuch der Website.

Um dieses Online-Angebot ständig optimieren zu können, setzt der WDR zusätzlich eine Lösung der Firma Webtrekk GmbH www.webtrekk.com zur Analyse der Verwendung der Website ein. Auf diese Weise kann die Nutzung der Website ausgewertet und wertvolle Informationen über die Bedürfnisse unserer Nutzer gesammelt werden. Durch die Ergebnisse dieser Analysen kann die Nutzerfreundlichkeit unserer Seite und die Qualität unserer Angebote erhöht werden.
### Analyse zur Optimierung durch Piano Analytics

Um diese Analysen durchführen zu können, sammelt Webtrekk aggregierte und anonyme statistische Daten. Bei diesen Daten handelt es sich um Verbindungsdaten ohne Personenbezug, die mit dem verwendeten Browser, der Anzahl der Seitenaufrufe und Visits, dem Navigationsverhalten und der Verweildauer des Internetusers auf einer Website, einer Seite usw. im Zusammenhang stehen.
Bei den „Programmieren mit der Maus“ werden Nutzungsinformationen über die Messverfahren von Piano Analytics in anonymisierter Form gesammelt und gespeichert. Piano Analytics löst die Messung durch Webtrekk ab. Auch hier wird eine kleine Bilddatei bzw. ein JavaScript in abrufbare Internetseiten eingebaut, um die Messung von Zugriffszahlen zu ermöglichen. Zudem werden Audio- und Videonutzung innerhalb des Players auf den Webseiten erfasst. Auch hier können in keinem Fall die gewonnenen Daten dazu verwendet werden, den Besucher dieser Webseite persönlich zu identifizieren. Die gesammelten Daten werden lediglich zur Verbesserung des Angebotes genutzt. Deshalb werden alle IP-Adressen nur in anonymisierter Form gespeichert. Eine andere Verwendung oder Weitergabe an Dritte erfolgt nicht. Sie können aber der vollkommen anonymen Analyse Ihres Surfverhaltens hier widersprechen.

Darüber hinaus werden bei diesem Verfahren sogenannte "permanente Cookies" eingesetzt. Diese Cookies werden in Form von Textdateien im Browser des Besuchers der Website gespeichert. Sie ermöglichen die Erkennung eines Nutzers bei einem wiederholten Besuch der Website.
Für einen Widerspruch müssen Sie die sogenannte „Opt-out“-Funktion aktivieren.
```render html
<PianoOptOut />
```

### Content Delivery Network

Bei der Verbreitung unserer Onlineangebote – insbesondere großer Mediendateien – bedienen wir uns eines sogenannten Content Delivery Network (CDN). Unser CDN ist ein Netz regional verteilter und über das Internet verbundener Server unserer technischen Dienstleister (Auftragsverarbeiter). Bei Abruf des Onlineangebots übermittelt der Internet-Browser bzw. das Programm, mit dem das Angebot abgerufen wird, diesen Dienstleistern automatisiert Informationen, die in entsprechenden Protokolldateien, den sog. Server-Logfiles, erhoben und auf Servern innerhalb der Europäischen Union verarbeitet werden. Die Server-Logfiles werden auf diesen Servern anonymisiert und dann ohne Personenbezug in die USA übermittelt. Dort werden die Server-Logfiles 90 Tage gespeichert und dann automatisiert gelöscht.

Bei den Server-Logfiles handelt es sich insbesondere um Details zum verwendeten Browser und Betriebssystem, ein Hinweis auf die Herkunft der zuvor besuchten Seiten (sog. Referral URL), die IP-Adresse des verwendeten Geräts, den Namen des Internet-Providers, sowie Datum, Uhrzeit aller Seiten-Aufrufe unter dem Angebot einschließlich der dabei übermittelten Datenmenge. Zusätzlich werden zur Optimierung der Videoqualität und Sicherstellung der Erreichbarkeit der Videos technische, nicht-personenbezogene Daten in Form von Video-Startzeit, technisch verursachte Unterbrechungen und Ladezeiten, empfangene Qualität und Netzwerkinformationen an Auswertungsservern erhoben.

Bei der Nutzung von wdr.de werden in der Regel zusätzlich Messdaten über das Angebot erhoben, um Metriken wie Ladezeiten, Übertragungsgeschwindigkeit, Dateigrößen etc. zu ermitteln (Monitoring). Dadurch kann die Funktionalität des Angebots auf dem jeweiligen Endgerät geprüft und verbessert werden. Diese Daten werden durch den technischen Dienstleister auf Servern innerhalb der Europäischen Union verarbeitet und dann anonymisiert und ohne Personenbezug zur Auswertung in die USA übermittelt.

Nach Ablauf der gesetzlichen Speicherfristen werden die anonymisierten Messdaten automatisiert gelöscht.
23 changes: 23 additions & 0 deletions src/lib/piano-analytics/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,26 @@ const pianoAnalytics =
? require('piano-analytics-js').pianoAnalytics
: null

export const paTrackingEnabled = !!pianoAnalytics

const OPTOUT_MODE = 'optout'
const VISITOR_COOKIES = ['_pcid', '_pctx']

export const paIsOptedOut = () =>
!!pianoAnalytics && pianoAnalytics.privacy.getMode() === OPTOUT_MODE

// The SDK stores the mode in its pa_privacy cookie and keeps the visitor ID
// cookies on opt-out, so remove them here.
export const paSetOptOut = (optOut) => {
if (!pianoAnalytics) return
pianoAnalytics.privacy.setMode(optOut ? OPTOUT_MODE : 'optin')
if (optOut) {
VISITOR_COOKIES.forEach((name) => {
document.cookie = `${name}=; path=/; max-age=0`
})
}
}

export const paSetConfig = () => {
if (!pianoAnalytics) return
pianoAnalytics.setConfigurations(SITES[process.env.TRACKING_MODE])
Expand All @@ -37,6 +57,9 @@ const pageLevelKeys = [
const sendEvent = (eventKey, data) => {
if (!pianoAnalytics) return

// Skipping the SDK entirely also keeps it from writing visitor ID cookies.
if (paIsOptedOut()) return

let properties = { ...DEFAULT_PROPERTY_VALUES }

switch (typeof data) {
Expand Down
Loading