Search by

messageagency / accme_analytics

aaronbauman

Install profile for Accessible Media Analytics from Harvard University Digital Accessibility Services.

Package info

bitbucket.org/messageagency/accme_analytics

Type:drupal-profile

pkg:composer/messageagency/accme_analytics

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

dev-main 2026-09-14 19:46 UTC

This package is not auto-updated.

Last update: 2026-09-22 15:11:08 UTC


README

Accessible Media Analytics is a Drupal installation profile that catalogues video content pulled from YouTube and Vimeo channels and tracks its caption and accessibility status. Channels are synced on a schedule; every video that gets ingested becomes a Captionable Media item whose caption status can be reviewed and updated directly from the content listing, including accessible, screen-reader-friendly inline editing.

This project is developed by Message Agency and sponsored by Harvard University Digital Accessibility Services.

Contents of this file

  • Introduction
  • The AccMe Analytics Project Template
  • Requirements
  • What's included
  • Installation
  • Configuration
  • Architecture: accme_analytics_module
  • Submodules
  • Continuous integration
  • Troubleshooting / FAQ
  • Maintainers

Introduction

Institutions with a large catalogue of YouTube and/or Vimeo video need a way to know, at a glance, which of those videos are captioned, which aren't, and which need a second look. AccMe Analytics answers that by:

  • Ingesting videos from one or more YouTube and/or Vimeo channels on a recurring schedule, via Drupal's queue system.
  • Recording each provider's own caption status automatically.
  • Giving reviewers a lightweight workflow (a caption status taxonomy, a review status, and free-text notes) to track what's actually been checked by a human, editable inline from the content listing.
  • Detecting stale media — video that's been deleted or unlisted upstream — so the catalogue reflects what's actually still published.

This is an installation profile, not a module: it defines the site's content types, taxonomies, user roles, and default configuration, and bundles the contributed and custom modules the site needs. It's meant to be the starting point for a new Drupal site, not something you add to an existing one.

  • Issue tracking and source: URL TK

The AccMe Analytics Project Template

The recommended way to start a new site is from the AccMe Analytics Project Template, a Composer project template (in the spirit of drupal/recommended-project) that's pre-wired to require this profile and its dependencies.

AccMe Analytics Project Templateplaceholder link; this template doesn't have a permanent home yet. Swap this in once it does.

If you'd rather wire an existing drupal/recommended-project-based codebase up to this profile yourself, see Installation below.

Requirements

  • PHP 8.3 or later.
  • Drupal core ^11.2.
  • A Composer-based Drupal codebase (this profile is distributed as a Composer package, messageagency/accme_analytics; it is not installable via a plain tarball drop-in).
  • MySQL/MariaDB (the profile enables Drupal's mysql core driver module).
  • To actually sync content, at least one provider needs credentials configured after install:

    The site installs and runs fine without either configured; the "Nag" notice on the admin status report just reminds you they're missing until you add at least one.

What's included

AccMe Analytics is a full distribution — installing it enables Drupal core and a curated set of contributed modules, in addition to the custom code described below. Some of the more notable ones:

Administration & editing

Access & authentication

Content & views

Operations

The full, authoritative list of dependencies is in composer.json and accme_analytics.info.yml.

Installation

  1. Starting from the AccMe Analytics Project Template (recommended) or your own drupal/recommended-project-based codebase with this profile required via Composer:

    composer require messageagency/accme_analytics
    
  2. Run the installer and select Accessible Media (AccMe) Analytics as the installation profile — either through the web installer, or from the command line with Drush:

    drush site-install accme_analytics
    
  3. During install, the site configuration form has extra fields specific to this profile: an optional custom logo (upload a file or point at an existing path), a YouTube API key, Vimeo API credentials, and optional Okta / OpenID Connect settings. All of these can be filled in later instead, from the configuration pages linked below.

  4. Once install finishes, you're taken straight to the welcome page at /admin/accme-analytics/welcome — quick links to add your first channel and configure providers, plus a walkthrough of how providers, channels, caption review, and cron fit together. It's not only shown once: return to it any time at that same URL as a refresher.

See the Drupal.org guide to installing distributions for general background on installing from a profile.

Configuration

  • Media Providers (/admin/structure/media-provider) — a configuration entity storing the API credentials for one YouTube or Vimeo account. Each provider has a Refresh operation to re-run its channel sync outside the normal cron schedule.
  • Channels — a Media Channel node points at a specific YouTube channel or Vimeo user/folder under a provider. Add one at a time from Add a channel, or add many at once from Bulk upload channels (/admin/structure/media-provider/upload) using a CSV file — see samples/youtube-channels.csv and samples/vimeo-channels.csv for the expected format. A channel only syncs while marked active.
  • Captionable Media — each ingested video is a node with: API Caption Status (detected automatically from the provider), Caption Status and Review Status (the manual review workflow, backed by the "Caption Status" taxonomy, editable inline from the content listing), and free-text Notes.
  • Cron & queues — on every cron run, each active channel is queued for sync; YouTube and Vimeo each have their own queue workers, scheduled independently via Ultimate Cron and inspectable via Queue UI. A separate stale-media queue (see Submodules) catches video that's disappeared from a provider's API response.
  • User roles — beyond Drupal's default Administrator, Anonymous, and Authenticated roles, the profile defines Manager, Reviewer, and Viewer, giving you a graduated level of access to channel/provider administration versus caption review versus read-only reporting.

Architecture: accme_analytics_module

accme_analytics_module is the custom module that does the actual work — providers, channels, syncing, and the review UI. The profile itself just enables it (and its submodules) and ships the content types, taxonomies, roles, and default configuration it depends on.

Plugin systems

  • Captionable Media Provider — a custom, annotation-based plugin type (@CaptionableMediaProvider, discovered by CaptionableMediaProviderPluginManager) that's the extension point for "how do we talk to this video service." Each plugin declares an id, a title/description shown when configuring a Media Provider, and a queue_handler class that does the actual fetching. The YouTube and Vimeo submodules each implement one; a Broken fallback plugin (the same pattern core uses for missing field widgets/formatters) is shown in its place if a provider's plugin ever goes missing, instead of fataling.
  • Queue workers — the accme_analytics queue worker (AccmeAnalyticsWorker) is derived, via its own deriver plugin, into one instance per active Media Channel, so cron queues up exactly the channels that need syncing. Each provider submodule supplies its own worker(s) for the finer-grained fetch (video, playlist) and stale-media detection work, built on shared VideoQueueWorkerBase / StaleMediaQueueWorkerBase classes.
  • Block, Field, and Views plugins — a Last Refresh block plugin surfaces the most recent sync time in the admin header; a custom field formatter and a handful of Views field/filter plugins support the caption review listing and its exposed filters.

Templates

accme_analytics_module uses Drupal's standard hook_theme() / hook_theme_suggestions_HOOK() pattern to layer its own templates on top of core and contrib ones, rather than creating a custom theme or overriding a theme's templates directly:

  • page--accme-analytics-module.html.twig is suggested for every page (via hook_theme_suggestions_page_alter()), acting as the module's site-wide page wrapper — more specific template suggestions (e.g. a node-type-specific one) still win.
  • views-view--accme-analytics-module.html.twig and export-icon--accme-analytics-module.html.twig do the same for all Views output and export icons respectively.
  • node--media-channel.html.twig is a normal, bundle-specific template override, used only for Media Channel nodes.

CSS build process

Styling is authored with Tailwind CSS utility classes and a small set of hand-written partials, then run through PostCSS (postcss-import, postcss-nested, postcss-extend, tailwindcss, autoprefixer — see postcss.config.js):

css/custom.css                 # entry point: @imports every partial below
css/partials/_base.css
css/partials/_navigation.css
css/partials/_form.css
css/partials/_text.css
css/partials/_channel.css
css/partials/_channels.css
css/partials/_dash.css
css/partials/_table.css
css/partials/_a11y.css
        │
        ▼  npm run build:css / watch:css
css/accme-analytics-module.css # compiled output, checked in and what actually ships

With Node.js installed (version pinned in .nvmrc) and the dev dependencies in package.json installed:

npm run build:css   # one-off build
npm run watch:css   # rebuild on change

The compiled CSS, plus a single JavaScript behaviors file (js/accme-analytics-module.js — small accessibility-focused Drupal.behaviors, e.g. announcing active Views exposed-filter values to screen readers), are attached together as one library, accme_analytics_module/global, which depends on Gin's own libraries and core's jquery/once. There's no JS build step — that file is written and shipped as plain, unminified Drupal-behaviors JavaScript.

Submodules

  • Accessible Media Analytics YouTube (accme_analytics_youtube) — implements the Captionable Media Provider plugin for YouTube, plus its queue workers.
  • Accessible Media Analytics Vimeo (accme_analytics_vimeo) — the same, for Vimeo.
  • Stale Media Handler (stale_media_handler) — finds and processes media no longer returned by a channel's provider API (for example, a video that was deleted or unlisted upstream), on its own Ultimate Cron schedule.

Support for an additional video provider can be added the same way YouTube and Vimeo were: implement the Captionable Media Provider plugin and the matching queue worker(s) in a new submodule.

Continuous integration

bitbucket-pipelines.yml runs a basic install sanity check — drush site-install accme_analytics against a throwaway SQLite database — on every push to main and on every pull request commit, using the official drupal Docker image. It's a smoke test, not a full test suite: it confirms the profile still installs cleanly, nothing more.

Troubleshooting / FAQ

The admin status report is nagging me about missing API credentials. That's expected until at least one provider (YouTube or Vimeo) has valid credentials configured — see Requirements and Configuration. The site works fine in the meantime; you just won't have any content syncing yet.

A channel isn't syncing. Confirm the channel is marked active and that its provider's credentials are valid (use the provider's Refresh operation to test outside the normal cron schedule). Check the queues in Queue UI and the job history in Ultimate Cron for errors.

I don't see media I know exists on the channel. Sync runs on a schedule; give it a full cron cycle, or use Refresh on the provider for an immediate check. If media was recently deleted or unlisted upstream, the Stale Media Handler submodule is what reconciles that — see Submodules.

Maintainers

Current maintainers:

This project has been sponsored by:

  • Harvard University Digital Accessibility Services URL TK