PHPackages                             gowelle/google-moderator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. gowelle/google-moderator

ActiveLibrary

gowelle/google-moderator
========================

Laravel package for text and image moderation using Google AI APIs with opt-in blocklists, multi-language support, and internal engine switching.

v2.0.0(1mo ago)05MITPHPPHP ^8.3CI passing

Since Dec 19Pushed 1mo agoCompare

[ Source](https://github.com/gowelle/google-moderator)[ Packagist](https://packagist.org/packages/gowelle/google-moderator)[ Docs](https://github.com/gowelle/google-moderator)[ RSS](/packages/gowelle-google-moderator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (28)Versions (5)Used By (0)

Google Moderator
================

[](#google-moderator)

[![Latest Version on Packagist](https://camo.githubusercontent.com/018024232db850bbc9a18bc52eb3dafde7dad01e4b7cf14b759d7cd3a89ee7f5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f676f77656c6c652f676f6f676c652d6d6f64657261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/google-moderator)[![Total Downloads](https://camo.githubusercontent.com/200a9f37d8271bcc5c67c1a3596cba697aa0d797154934df7ed1468044125fb1/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f676f77656c6c652f676f6f676c652d6d6f64657261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/google-moderator)[![PHP Version](https://camo.githubusercontent.com/9b80921cfd937715f91f8328b962c189116fad6f1b8e0e47fee2a0dc816899b8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f676f77656c6c652f676f6f676c652d6d6f64657261746f722e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/gowelle/google-moderator)[![Tests](https://github.com/gowelle/google-moderator/actions/workflows/tests.yml/badge.svg?style=flat-square)](https://github.com/gowelle/google-moderator/actions/workflows/tests.yml)[![License](https://camo.githubusercontent.com/942e017bf0672002dd32a857c95d66f28c5900ab541838c6c664442516309c8a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)

A Laravel package for **text and image moderation** using Google AI APIs, with opt-in blocklists, multi-language support, and internal engine switching.

Table of Contents
-----------------

[](#table-of-contents)

- [Features](#features)
- [Requirements](#requirements)
- [Installation](#installation)
- [Configuration](#configuration)
- [Quick Start](#quick-start)
- [Validation Rules](#validation-rules)
- [ModerationResult API](#moderationresult-api)
- [Blocklists](#blocklists)
- [Engine Comparison](#engine-comparison)
- [Thresholds](#thresholds)
- [Events](#events)
- [Testing](#testing)
- [Changelog](#changelog)

Features
--------

[](#features)

- 🔤 **Text Moderation** - Analyze text for toxic, harmful, or inappropriate content
- 🖼️ **Image Moderation** - Detect adult, violent, or racy content in images
- 🌍 **Multi-Language Support** - Swahili-first, with support for any language via custom blocklists
- 📋 **Custom Blocklists** - File or database-backed blocklists with regex support
- 🔄 **Engine Switching** - Switch between Natural Language API, Vision API, or Gemini
- ⚡ **Caching** - Built-in caching for blocklist terms
- 🧪 **Testable** - Fully testable with mocked Google clients

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 11.x, 12.x, or 13.x
- Google Cloud account with enabled APIs

Installation
------------

[](#installation)

```
composer require gowelle/google-moderator
```

Publish the configuration:

```
php artisan vendor:publish --tag="google-moderator-config"
```

Publish the migrations:

```
php artisan vendor:publish --tag="google-moderator-migrations"
php artisan migrate
```

Configuration
-------------

[](#configuration)

### Authentication

[](#authentication)

The package supports multiple authentication methods:

```
// config/google-moderator.php

'auth' => [
    // Option 1: Path to service account JSON file
    'credentials_path' => env('GOOGLE_APPLICATION_CREDENTIALS'),

    // Option 2: Inline JSON (for serverless environments like Vapor)
    'credentials_json' => env('GOOGLE_CREDENTIALS_JSON'),

    // Option 3: Project ID for Application Default Credentials
    'project_id' => env('GOOGLE_CLOUD_PROJECT'),
],
```

### Engine Selection

[](#engine-selection)

```
'engines' => [
    'text' => 'natural_language', // or 'gemini'
    'image' => 'vision',          // or 'gemini'
],
```

Quick Start
-----------

[](#quick-start)

### Text Moderation

[](#text-moderation)

```
use Gowelle\GoogleModerator\Facades\Moderation;

$result = Moderation::text(
    text: 'This is some content to moderate',
    language: 'en'
);

if ($result->isSafe()) {
    // Content is safe
} else {
    // Content was flagged
    foreach ($result->flags() as $flag) {
        echo "{$flag->category}: {$flag->severity}";
    }
}
```

### Image Moderation

[](#image-moderation)

```
use Gowelle\GoogleModerator\Facades\Moderation;

// From file path
$result = Moderation::image('/path/to/image.jpg');

// From URL
$result = Moderation::image('https://example.com/image.jpg');

if ($result->isUnsafe()) {
    // Handle unsafe image
}
```

Validation Rules
----------------

[](#validation-rules)

The package provides custom Laravel validation rules for easy integration into your requests and validators.

### ModeratedText

[](#moderatedtext)

Validates that a string is safe according to your configured text engines and blocklists.

```
use Gowelle\GoogleModerator\Rules\ModeratedText;

$request->validate([
    'bio' => ['required', 'string', new ModeratedText()],

    // With custom failure message
    'comment' => ['required', new ModeratedText('Please be polite.')],
]);
```

### ModeratedImage

[](#moderatedimage)

Validates pictures (uploads, paths, or URLs) against image moderation engines.

```
use Gowelle\GoogleModerator\Rules\ModeratedImage;

$request->validate([
    'avatar' => ['required', 'image', new ModeratedImage()],
]);
```

ModerationResult API
--------------------

[](#moderationresult-api)

```
$result = Moderation::text($content, 'sw');

// Safety checks
$result->isSafe();              // bool
$result->isUnsafe();            // bool
$result->confidence();          // float|null

// Flag access
$result->flags();               // array
$result->apiFlags();            // Flags from Google API only
$result->blocklistFlags();      // Flags from blocklist only
$result->highSeverityFlags();   // High severity flags only
$result->hasHighSeverityFlags(); // bool

// Metadata
$result->provider();            // 'google' or 'blocklist'
$result->engine();              // 'natural_language', 'vision', 'gemini'

// Grouping
$result->flagsByCategory();     // array

// Serialization
$result->toArray();
json_encode($result);
```

Blocklists
----------

[](#blocklists)

> **💡 Bonus Feature**: Google APIs don't provide customizable term blocking. This package includes a complete blocklist system so you can catch domain-specific terms, slang, or phrases that the AI might miss.

### Why Blocklists?

[](#why-blocklists)

- **Domain-specific terms** - Block product names, competitor mentions, or industry jargon
- **Regional slang** - Catch offensive terms in local dialects (especially useful for Swahili and other languages)
- **Zero-tolerance words** - Instantly flag specific terms regardless of AI confidence
- **Runs after AI analysis** - Combines AI intelligence with your custom rules

### Enabling Blocklists

[](#enabling-blocklists)

```
'blocklists' => [
    'enabled' => true,
    'storage' => 'database', // or 'file'
    'languages' => ['en', 'sw', 'fr'], // any languages
],
```

### File-Based Blocklists

[](#file-based-blocklists)

Create JSON files in `storage/blocklists/`:

```
// storage/blocklists/sw.json
{
    "language": "sw",
    "terms": [
        { "value": "offensive_word", "severity": "high" },
        { "value": "*partial_match*", "severity": "medium" }
    ]
}
```

Publish sample files:

```
php artisan vendor:publish --tag="google-moderator-blocklists"
```

### Database Blocklists

[](#database-blocklists)

Store terms in the database for easy management via admin panels.

Note

**Architecture Note**: This package uses `DB::table('blocklist_terms')` directly for performance and does **not** include an Eloquent model. You can interact with the table using the `DB` facade or the provided Blocklist repository methods.

Ensure you have run the migrations:

```
php artisan migrate
```

Table schema structure:

```
// Example of accessing the table directly
DB::table('blocklist_terms')->insert([
    'language' => 'sw',         // string(10)
    'value' => 'bad_word',      // string
    'severity' => 'high',       // enum('low', 'medium', 'high')
    'is_regex' => false,        // boolean
    'created_at' => now(),
    'updated_at' => now(),
]);
```

```
// Add terms programmatically
Moderation::blocklist()->addTerm('sw', 'neno_baya', 'high');
Moderation::blocklist()->addTerm('en', '*spam*', 'medium');
```

Import/export via Artisan:

```
php artisan moderator:blocklist:import storage/blocklists/sw.json --language=sw
php artisan moderator:blocklist:export --language=sw --output=exported.json
```

### Pattern Matching

[](#pattern-matching)

Blocklist terms support three matching modes:

PatternExampleMatchesExact`badword`"This is badword here" ✅ "badwordy" ❌Wildcard`*offensive*`"very offensive content" ✅Regex`/\b(bad|terrible)\b/i`"This is bad" ✅Engine Comparison
-----------------

[](#engine-comparison)

FeatureNatural LanguageVisionGeminiText Moderation✅❌✅Image Moderation❌✅✅Toxicity Detection✅ (16 categories)❌✅SafeSearch❌✅✅Multi-language✅N/A✅CostPer requestPer imagePer requestDefault✅ Text✅ Image❌ OptionalThresholds
----------

[](#thresholds)

Configure sensitivity per category:

```
'thresholds' => [
    // Text (0.0 - 1.0, lower = more strict)
    'toxic' => 0.7,
    'severe_toxic' => 0.5,
    'profanity' => 0.7,

    // Image (VERY_UNLIKELY to VERY_LIKELY)
    'adult' => 'LIKELY',
    'violence' => 'LIKELY',
    'racy' => 'POSSIBLE',
],
```

Events
------

[](#events)

The package dispatches a `ContentFlagged` event whenever content is flagged as unsafe:

```
use Gowelle\GoogleModerator\Events\ContentFlagged;
use Illuminate\Support\Facades\Event;

// In your EventServiceProvider or listener
Event::listen(ContentFlagged::class, function (ContentFlagged $event) {
    Log::warning('Unsafe content detected', [
        'type' => $event->type,           // 'text' or 'image'
        'categories' => $event->categories(),
        'is_high_severity' => $event->isHighSeverity(),
        'flags' => $event->result->flags(),
    ]);

    // Take action: notify moderators, block submission, etc.
});
```

### ContentFlagged Event Properties

[](#contentflagged-event-properties)

```
$event->result;      // ModerationResult DTO
$event->type;        // 'text' or 'image'
$event->content;     // Original text or image path
$event->language;    // Language code (for text)
$event->metadata;    // Additional context

// Helper methods
$event->isText();           // bool
$event->isImage();          // bool
$event->categories();       // array of flagged categories
$event->isHighSeverity();   // bool
```

### Disabling Events

[](#disabling-events)

```
// config/google-moderator.php
'events' => [
    'enabled' => false,
],
```

Testing
-------

[](#testing)

```
# Unit tests
composer test

# With coverage
composer test-coverage

# Static analysis
composer analyse

# Code style
composer format-test
```

### Mocking in Tests

[](#mocking-in-tests)

```
use Gowelle\GoogleModerator\Facades\Moderation;
use Gowelle\GoogleModerator\DTOs\ModerationResult;

Moderation::shouldReceive('text')
    ->with('test content', 'en')
    ->andReturn(ModerationResult::safe('google', 'natural_language'));
```

Changelog
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for recent changes.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover a security vulnerability, please send an email to .

Credits
-------

[](#credits)

- [Gowelle](https://github.com/gowelle)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

41

—

FairBetter than 89% of packages

Maintenance89

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~92 days

Total

2

Last Release

58d ago

Major Versions

v1.0.0 → v2.0.02026-03-21

PHP version history (2 changes)v1.0.0PHP ^8.2

v2.0.0PHP ^8.3

### Community

Maintainers

![](https://www.gravatar.com/avatar/d77e8d8a848a61e17982aa6353f62833194bee3d956314b3eb80baa539f4cf29?d=identicon)[gowelle](/maintainers/gowelle)

---

Top Contributors

[![gowelle](https://avatars.githubusercontent.com/u/87917924?v=4)](https://github.com/gowelle "gowelle (17 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (10 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (10 commits)")

---

Tags

laravelgooglevisionGemininatural-languagecontent moderationmoderationblocklisttext-moderationimage-moderationswahili

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/gowelle-google-moderator/health.svg)

```
[![Health](https://phpackages.com/badges/gowelle-google-moderator/health.svg)](https://phpackages.com/packages/gowelle-google-moderator)
```

###  Alternatives

[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[spatie/laravel-health

Monitor the health of a Laravel application

86910.0M83](/packages/spatie-laravel-health)[spatie/laravel-livewire-wizard

Build wizards using Livewire

4061.0M4](/packages/spatie-laravel-livewire-wizard)[clickbar/laravel-magellan

This package provides functionality for working with the postgis extension in Laravel.

423715.4k1](/packages/clickbar-laravel-magellan)[spatie/laravel-prometheus

Export Laravel metrics to Prometheus

2651.3M6](/packages/spatie-laravel-prometheus)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
