# Discourse Image Filter

**URL:** https://meta.discourse.org/t/discourse-image-filter/163927
**Category:** Plugin
**Tags:** broken
**Created:** [September 14, 2020, 6:54am UTC](https://meta.discourse.org/t/discourse-image-filter/163927 "2020-09-14T06:54:32Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [September 14, 2020, 6:54am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/1 "2020-09-14T06:54:32Z")

</div>

This plugin uses the Google Cloud Vision API to restrict uploading explicit images to the forum. It accounts for all the images uploaded i.e. avatars, logos, etc.

It uses the upload error popup to display a message explaining which violations resulted in the restriction of the image upload.

The acceptable limits can be set via the site settings.

* * *

### Setup

Steps:

1. Create a service account on google cloud [Create service accounts &nbsp;|&nbsp; Identity and Access Management (IAM) &nbsp;|&nbsp; Google Cloud Documentation](https://cloud.google.com/iam/docs/creating-managing-service-accounts)  
Google will trigger a download of a JSON file. Store its contents safely.

2. Paste these lines at the bottom of env section in your app.yml

- 
#### How to setup `GOOGLE_PRIVATE_KEY` parameter?

  - Paste the key in the json file to code editor.
  - Use `find and replace` and replace `\n` with `\\n`
  - Copy the result and paste it in app.yml in front of `GOOGLE_PRIVATE_KEY` wrapping it in single quotes `' ' `.

1. Now follow the regular steps of installing the plugin.

* * *

### Plugin Settings

`if_adult_max_acceptable`: Maximum acceptable level of the category `adult`  
`if_spoof_max_acceptable`: Maximum acceptable level of the category `spoof`  
`if_medical_max_acceptable`: Maximum acceptable level of the category `medical`  
`if_violence_max_acceptable`: Maximum acceptable level of the category `violence`  
`if_racy_max_acceptable`: Maximum acceptable level of the category `racy`

You can read about these criteria and the API itself in detail here. [Detect explicit content (SafeSearch) &nbsp;|&nbsp; Cloud Vision API &nbsp;|&nbsp; Google Cloud Documentation](https://cloud.google.com/vision/docs/detecting-safe-search)

[📄 Get the code](https://github.com/paviliondev/discourse-image-filter)

[🙋‍♀️ Request a feature](https://thepavilion.io/w/feature-request)

[🐛 Report a bug](https://thepavilion.io/w/bug-report)

### Development Notes

> ****
>
> For using in a dev environment on macos, add this line to your .bash\_profile file  
> `export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES`

#### Lost?

- Not sure how to install a plugin? [Follow the steps here](https://meta.discourse.org/t/install-plugins-in-discourse/19157).  
  

Thanks @Terrapop for sponsoring the plugin.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [September 14, 2020, 7:10am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/2 "2020-09-14T07:10:11Z")

</div>

@riking

I made this PR [FIX: erroneous condition which would cause an error if ever satisfied by fzngagan · Pull Request #10605 · discourse/discourse · GitHub](https://github.com/discourse/discourse/pull/10605) because I realized that the upload error popup wouldn’t display if there’s was a rails side exception while uploading avatars/logos. It works well while uploading from composer. I thought it would be a nice upstream change to incorporate.

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [September 14, 2020, 7:14am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/3 "2020-09-14T07:14:02Z")

</div>

Thanks for the ping, missed the Github notification.

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [September 14, 2020, 7:18am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/4 "2020-09-14T07:18:31Z")

</div>

Thanks a lot for the merge. It helps discourse and my plugin both.

---

<div class="post-metadata">

### Author: ![Terrapop](https://avatars.discourse-cdn.com/v4/letter/t/ecd19e/32.png) [@Terrapop](https://meta.discourse.org/u/Terrapop)
#### Post date: [September 14, 2020, 9:28am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/5 "2020-09-14T09:28:18Z")

</div>

Great, thanks for your help @fzngagan making this possible, was a pleasure working with you.

**For all communities that have child-safe COPPA requirements or want to stay safe in terms of Adsense, or simply don’t want to have gore or nude images anywhere this plugin is a must-have.**

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 9, 2020, 3:36pm UTC](https://meta.discourse.org/t/discourse-image-filter/163927/6 "2020-10-09T15:36:15Z")

</div>

@Razcle  
This might be something of interest for you

---

<div class="post-metadata">

### Author: ![Razcle](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/razcle/32/196610_2.png) [@Razcle](https://meta.discourse.org/u/Razcle)
#### Post date: [October 9, 2020, 3:53pm UTC](https://meta.discourse.org/t/discourse-image-filter/163927/7 "2020-10-09T15:53:24Z")

</div>

Thanks Faizaan! I was thinking about making something more focussed on language understanding and customisable. Have you had any experience with that?

R

---

<div class="post-metadata">

### Author: ![fzngagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/fzngagan/32/259349_2.png) [@fzngagan](https://meta.discourse.org/u/fzngagan)
#### Post date: [October 9, 2020, 4:23pm UTC](https://meta.discourse.org/t/discourse-image-filter/163927/8 "2020-10-09T16:23:38Z")

</div>

@jahan_gagan might have something to say on NLP.

---

<div class="post-metadata">

### Author: ![jahan\_gagan](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/jahan_gagan/32/501948_2.png) [@jahan\_gagan](https://meta.discourse.org/u/jahan_gagan)
#### Post date: [October 10, 2020, 10:02am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/10 "2020-10-10T10:02:31Z")

</div>

I had tried the `stackoverflow dataset` for `tags prediction` , after that I tried same code for discourse dataset, but due to less volume of data at discourse that code didn’t work here

---

<div class="post-metadata">

### Author: ![Maxpain](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maxpain/32/231717_2.png) [@Maxpain](https://meta.discourse.org/u/Maxpain)
#### Post date: [August 25, 2021, 6:52am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/11 "2021-08-25T06:52:47Z")

</div>

What scopes do I need in my service account? I’m getting “Request had insufficient authentication scopes".

---

<div class="post-metadata">

### Author: ![No\_One](https://avatars.discourse-cdn.com/v4/letter/n/9fc29f/32.png) [@No\_One](https://meta.discourse.org/u/No_One)
#### Post date: [August 25, 2021, 7:28am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/12 "2021-08-25T07:28:57Z")

</div>

This can help? Runs completely on client side

[text toxicity model](https://github.com/tensorflow/tfjs-models/tree/master/toxicity)

 ![image](https://global.discourse-cdn.com/meta/original/3X/8/8/88da5fb67b27d528de4cc065562d4ea725e0c735.jpeg)

---

<div class="post-metadata">

### Author: ![Terrapop](https://avatars.discourse-cdn.com/v4/letter/t/ecd19e/32.png) [@Terrapop](https://meta.discourse.org/u/Terrapop)
#### Post date: [August 26, 2021, 11:31am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/13 "2021-08-26T11:31:03Z")

</div>

This plugin is about IMAGES, not text.

For text there is a Google Perspective plugin available based on the Jigsaw engine:

> [@Discourse Google Perspective API](https://meta.discourse.org/t/google-perspective-api-plugin/98733):
>
> discourse2Summary Google Perspective API is the official Google Perspective API plugin for Discoursehammer_and_wrenchRepository Link [https://github.com/discourse/discourse-perspective-api](https://github.com/discourse/discourse-perspective-api)open_bookInstall Guide [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157)Features What is the Perspective API? From [the official site](https://www.perspectiveapi.com/), “Perspective is an API that makes it easier to host better conversations.The API uses machine learning models to score the perceived impact a comment might h…

---

<div class="post-metadata">

### Author: ![Don](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/don/32/228726_2.png) [@Don](https://meta.discourse.org/u/Don)
#### Post date: [July 28, 2024, 5:20am UTC](https://meta.discourse.org/t/discourse-image-filter/163927/14 "2024-07-28T05:20:22Z")

</div>

Hello 👋 Is this plugin still workable? I just saw that the last commit was about 4 years ago. Thanks 🙂

---

<div class="post-metadata">

### Author: ![Don](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/don/32/228726_2.png) [@Don](https://meta.discourse.org/u/Don)
#### Post date: [August 2, 2024, 4:54pm UTC](https://meta.discourse.org/t/discourse-image-filter/163927/15 "2024-08-02T16:54:27Z")

</div>

I’ve tried to install it on a test instance but seems there is a gem issue. Failed the rebuild. Hopefully it is fixable. 🤞 Maybe these gems just deprecated…

```plaintext
rake aborted!

Gem::LoadError: can't activate google-protobuf-3.13.0-x86_64-linux, already activated google-protobuf-4.27.3-x86_64-linux (Gem::LoadError)

/var/www/discourse/lib/plugin_gem.rb:25:in `load'

/var/www/discourse/lib/plugin/instance.rb:835:in `gem'

/var/www/discourse/plugins/discourse-image-filter/plugin.rb:12:in `activate!'

/var/www/discourse/lib/plugin/instance.rb:778:in `instance_eval'

/var/www/discourse/lib/plugin/instance.rb:778:in `activate!'

/var/www/discourse/lib/discourse.rb:348:in `block in activate_plugins!'

/var/www/discourse/lib/discourse.rb:345:in `each'

/var/www/discourse/lib/discourse.rb:345:in `activate_plugins!'

/var/www/discourse/config/application.rb:231:in `block in <class:Application>'

/var/www/discourse/lib/plugin.rb:6:in `initialization_guard'

/var/www/discourse/config/application.rb:231:in `<class:Application>'

/var/www/discourse/config/application.rb:75:in `<module:Discourse>'

/var/www/discourse/config/application.rb:74:in `<top (required)>'

/var/www/discourse/Rakefile:7:in `<top (required)>'

/var/www/discourse/vendor/bundle/ruby/3.3.0/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'

/usr/local/bin/bundle:25:in `load'

/usr/local/bin/bundle:25:in `<main>'

(See full trace by running task with --trace)

I, [2024-08-02T16:48:02.872895 #1] INFO -- : gem install os -v 1.1.1 -i /var/www/discourse/plugins/discourse-image-filter/gems/3.3.3 --no-document --ignore-dependencies --no-user-install

Successfully installed os-1.1.1

1 gem installed

gem install google-protobuf -v 3.13.0 -i /var/www/discourse/plugins/discourse-image-filter/gems/3.3.3 --no-document --ignore-dependencies --no-user-install

Successfully installed google-protobuf-3.13.0-x86_64-linux

1 gem installed

I, [2024-08-02T16:48:02.886926 #1] INFO -- : Terminating async processes

I, [2024-08-02T16:48:02.888160 #1] INFO -- : Sending INT to HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/13/bin/postmaster -D /etc/postgresql/13/main pid: 36

I, [2024-08-02T16:48:02.888588 #1] INFO -- : Sending TERM to exec chpst -u redis -U redis /usr/bin/redis-server /etc/redis/redis.conf pid: 98

2024-08-02 16:48:02.888 UTC [36] LOG: received fast shutdown request

98:signal-handler (1722617282) Received SIGTERM scheduling shutdown...

2024-08-02 16:48:02.892 UTC [36] LOG: aborting any active transactions

98:M 02 Aug 2024 16:48:02.896 # User requested shutdown...

98:M 02 Aug 2024 16:48:02.897 * Saving the final RDB snapshot before exiting.

2024-08-02 16:48:02.906 UTC [36] LOG: background worker "logical replication launcher" (PID 51) exited with exit code 1

2024-08-02 16:48:02.909 UTC [46] LOG: shutting down

98:M 02 Aug 2024 16:48:02.939 * DB saved on disk

98:M 02 Aug 2024 16:48:02.939 # Redis is now ready to exit, bye bye...

2024-08-02 16:48:02.949 UTC [36] LOG: database system is shut down

FAILED

--------------------

Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 571 exit 1>

Location of failure: /usr/local/lib/ruby/gems/3.3.0/gems/pups-1.2.1/lib/pups/exec_command.rb:132:in `spawn'

exec failed with the params {"cd"=>"$home", "tag"=>"migrate", "hook"=>"db_migrate", "cmd"=>["su discourse -c 'bundle exec rake db:migrate'"]}

bootstrap failed with exit code 1

**FAILED TO BOOTSTRAP** please scroll up and look for earlier error messages, there may be more than one.

./discourse-doctor may help diagnose the problem.

9213a43b80e800c6f2b1d0adc0663ec82a483b860f0302b8ebabc8a3b2bb0619

```

I tagged this as #broken.
