Moderating Actions on Stream's Activity Feeds service
Tags: getstreamio, aws, lambda, compliance
Published: 2021-07-11 07:04:26


######(headline image by [Claudio Schwarz](https://unsplash.com/@purzlbaum))
---

> This is for [Stream](https://getstream.io/activity-feeds/), or getstream.io's Activity Feeds service. This block is here so people who are searching for getstream.io can find it!  I'm never sure how to referr to the company, as just calling it 'Stream' when discussing it in a development setting gets very confusing :(

---

## INTRO
In this tutorial, we're going to talk about, and solve, a problem with [Stream's Activity Feeds](https://getstream.io/activity-feeds/) product: there's no build-in moderation tools.

Is that a problem?  Yes, it really is.  Skipping past the problems of the legals of [who is liable](https://www.dlapiper.com/en/japan/insights/publications/2020/12/ipt-news-q4-2020/whos-responsible-for-content-posted-on-the-internet-section-230-explained/) for [content on your platform](https://www.reuters.com/article/us-britain-tech-regulation-idUSKBN2060Q7), there's also compliance for User Generated Content on both [App Store](https://developer.apple.com/app-store/review/guidelines/#user-generated-content) and [Google Play](https://support.google.com/googleplay/android-developer/answer/9878810?hl=en-GB&ref_topic=9877466) to consider.  


We're going to look at setting up your Activity Feed Types so we can create a firewall between Activities being added, and those being viewable.  We're also going to talk about a way of handing image moderation: AWS's [Rekognition](https://aws.amazon.com/rekognition/) service.

This isn't a tutorial on how to implement this, rather a guide on how to set up your Activity Feed Types so we can add moderation and other automation. 

 I'll cover the practical 'how-do' in another article (and I'll update this once I've written it!)


## WHAT YOU'LL NEED
* AWS account, and some basic understanding of what SQS is, and what Lambdas are,
* Getstream account, and some knowedge of the Activity Feed service

## AWS REKOGNITION
[AWS Rekognition](https://docs.aws.amazon.com/rekognition/latest/dg/moderation.html) is a machine learning tool that Amazon have trained over billions of images and videos, and we can use that power just by calling a simple API. By using this, we don't have to have people looking at each image manually, and have to deal with all the problems that come with that.  

You'll want to be using the '[Detecting Inappropriate Images](https://docs.aws.amazon.com/rekognition/latest/dg/procedure-moderate-images.html)' part.

We need to upload the image to AWS Rekognition (which is built into the AWS SDK), and it will return a series of Labels, along with a Confidence (a number on how sure AWS is that this Label is right).  Then we can use those to determine if the images need to be hidden or not.

You can see in the AWS Rekognition documentation the list of Labels you can get back, and from that you can choose what kind of images you do and don't want on your platform.


## STREAM
Getting the Activity Feeds Types right here is the key.  We need to create a gap between the Activities created by users, and those activites being seen by other users.

### Common Activity Feed Type setup
Imagine we want a platform where we have content creators and content viewers.  You could set it so each Creator has a `timeline` feed, and each Viewer has a `notification` feed that is subscribed to one or many Creator's Timelines.   

Something like this:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1gtq4pdnxuwdtli7qy8s.png)

Any time `creator-0001` publishes to their `timeline` feed, it will appear in the `notification` feed for `viewer-9876`. 

You can see here, there is no way we can stop this happening.  If `creator-0001` posts something we don't want, we're in trouble.

### Moderation Activity Feed Type setup
The solution is to create some kind of break between Creator publishing something, and the Viewer seeing it before we've had a chance to moderate it. 

Stream provide a way of doing this.  For each Activity Feed Type you can it up to puiblish the Activity to an SQS queue, so we can grab it from the queue, look at it, then publish it somehow.

Something like this:
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hidqgmumg5ojay9gzuvk.png)
 
This method allows us to _code the link_ between the `unpublished_timeline:creator-0001` and the `published_timeline:creator-0001` feeds, and using AWS Rekognition we can inject image moderation into that step.  In fact, with this step, we can do any kind of moderation or action based on the content published we want.


Your Lambda should take the code from the SQS queue (something Stream have [written a tutorial on](https://getstream.io/blog/using-the-stream-real-time-firehose-with-aws-sqs-lambda-and-sns/)), and use the AWS SDK to send the image to Rekogntion.  Once you have your Labels back, you can then choose to ''copy'' the activity from one feed to another.

There isn't a way of copying an Activity from one feed to another that I know off, so you have to re-create the Activity on the `published` feed, and remove it from the `unpublished` feed.. if someone from Stream knows a better way to do this, I would appreciate you letting me know.

## CONCLUSION
With this set up, you will be able to perform any kind of moderation you wish on any Action published on your platform.  Using Lambdas and SQS means your solution will scale with your demands, and you can use this model to build in any kind of events.

What about using SQS feeds to manage push notifications, or emails to users when content is published? It's also a good way of getting data _out_ of getstream into something you can look at and use without over-consuming your API usage.

I would be super interested in knowing if this solution works for you, or how you have approached this problem! Please reach out on Twitter to [@scampiuk](https://twitter.com/scampiuk) and let me know how it goes.