Skip to content

Getting started with COPPA🔗

To integrate COPPA, you need to follow a few simple steps

Step 1. Import the GDPR module🔗

  • Add MRGSGDPR module

    Unity:

    Adding to the project (general instruction)

    Step 1. Add Sources

    To add MRGS to a project via the Unity Package Manager (available from Unity 2018+) simply add a scopedRegistries section to the Packages/manifest.json file by adding the following entry:

    {
        "dependencies": {
            ...
        },
        "scopedRegistries": [
                {
                    "name": "MRGS",
                    "url": "https://mrgs-nexus.my.games/repository/mrgs-uninty-plugins/",
                    "scopes": [
                        "games.my.mrgs"
                    ]
                }
        ]
    }
    

    Alternatively, you can click Edit -> Project Settings -> Package Manager -> '+' in scoped registry section, and fill in the fields according to the data above.

    Step 2. Add dependency

    • Click Window -> Package Manager -> select 'Packages: MyRegistries' from dropdown list, select package MRGSGDPR from the list, then click "Install"
    • Import the module: using MRGS;
    • Download the latest version of the library. Unzip the archive.
    • (For unitypackage integration) In Unity, click Assets -> Import Package -> Custom Package, and select the games.my.mrgs.gdpr.unitypackage package from the downloaded archive.
    • (For tgz integration) In Unity, click Window -> Package Manager -> '+' -> Add package from tarball, and select the games.my.mrgs.gdpr-<version> package. tgz from the downloaded archive.
    • Import the module: using MRGS;

    iOS:

    Adding to the project (general instruction)

    Step 1: Add dependencies

    Via Package collection

    • In Xcode select File > Add Packages
    • Select "+" > "Add Swift Package Collection"
    • Insert URL: https://mrgs-nexus.my.games/repository/ios-sdks/MRGSPackageCollection.json
    • Select module MRGSGDPR from "MRGS Package Collection".
    • Or you can select "MRGS" package from "MRGS Package Collection" (contains all mrgs modules as products) and then select "MRGS/GDPR" product only.

    Individual packages

    • In Xcode select File > Add Packages
    • In the search bar at the top right, paste the URL: https://mrgs-gitea.my.games/mrgs/mrgsgdpr-ios-sdk.git
    • Add a module to your project
    • Or you can paste the url https://mrgs-gitea.my.games/mrgs/ios-sdks.git to include the "MRGS" package which contains all mrgs modules as products and then select only the product" MRGS/GDPR".

    Step 2: Add support for ObjectiveC categories

    • Set the -ObjC flag in the "Other linker Flags" field in the project settings.
    • Import the module in code: @import MRGServiceKit; or @import MRGSGDPR; or #import <MRGSGDPR/MRGSGDPR.h>

    Step 1. Add Sources

    In your podfile, add sources to the top of the file:

    source 'https://github.com/CocoaPods/Specs.git' # For main repo
    source 'https://mrgs-gitea.my.games/mrgs/cocoapods-specs.git'  # For MRGS repo
    

    Step 2: Add dependencies

    Add the latest version of MRGSGDPR to target:

    To add via subspecs:

    target 'MyProject' do
        pod 'MRGS', '~> 5.0.0', :subspecs => ['GDPR']
    end
    

    To add via individual modules:

    target 'MyProject' do
        pod 'MRGSGDPR', '~> 5.0.0'
    end
    

    To add all mrgs modules:

    target 'MyProject' do
        pod 'MRGS/AllKits', '~> 5.0.0'
    end
    

    Step 3: Install dependencies

    • Run pod install (or pod install --repo-update if necessary)
    • Import the module in code: @import MRGServiceKit; or @import MRGSGDPR; or #import <MRGSGDPR/MRGSGDPR.h>

    Step 1: Add dependencies

    Add the dependency to your Cartfile:

    binary "https://mrgs-nexus.my.games/repository/ios-sdks/MRGSGDPR/MRGSGDPR.json" ~> 5.0.0
    

    Step 2: Install dependencies

    • Run carthage update --use-xcframeworks
    • Add downloaded frameworks to your project (make sure "do not embed" option is enabled)
    • Set the -ObjC flag in the "Other linker Flags" field in the project settings.
    • Import the module in code: @import MRGServiceKit; or @import MRGSGDPR; or #import <MRGSGDPR/MRGSGDPR.h>
    • Download the latest version of the library. Unzip the archive.
    • Add MRGSGDPR.xcframework from the downloaded archive to your project (Drag the libraries to the "Linked frameworks and Libraries" section) (Also contains MRGSGDPR.framework for compatibility - fat framework)

    • Add bundle with resources:

      • Add MRGSGDPRResources.bundle to the project by dragging it into the project structure.
      • Go to the "Copy Bundle Resources" section in the "Build Phases" tab, click "+", and select the desired bundle.
    • Set the -ObjC flag in the "Other linker Flags" field in the project settings.

    • Import the module in code: @import MRGSGDPR; or #import <MRGSGDPR/MRGSGDPR.h>
    • Also, you can add the MRGServiceKit.h and module.modulemap files from the archive to your project, or specify the path to them in the project settings in the Build Settings -> Header search paths section. Now, instead of importing each of our frameworks separately, you can only import one header file: @import MRGServiceKit;

    Android:

    Add dependencies into build.gradle file:

    dependencies {
        def mrgsVersion = "6.x.x"
    
        implementation "games.my.mrgs:gdpr:$mrgsVersion"
    }
    

    Copy the MRGSGDPR.aar file into the libs directory of your project. Add the necessary dependencies to the build.gradle file:

    dependencies {
        //...
        implementation(name: 'MRGSGDPR', ext:'aar')
    
        implementation 'androidx.appcompat:appcompat:1.6.1'
    }
    

Step 2. Prepare MRGSCOPPA class🔗

To work, use the MRGSCOPPA class. First of all, you need to pass the parameters necessary for its operation to the class, without which any method will return an error:

MRGSCOPPA.Instance.Setup(APP_ID, APP_SECRET);
[[MRGSCOPPA sharedInstance] setupForAppId:APP_ID andSecret:APP_SECRET];
MRGSCOPPA.getInstance().setUp(APP_ID, APP_SECRET);

Step 3. Configure the display parameters🔗

Then you need to set all the settings you need:

  • disableAccessForUnderagedUsers - banning users under 13 from entering the game (that is, sending letters to their parents), they will see a window with a text about banning the game(there are examples on COPPA description page)
  • You can override the standard windows(HTML) by replacing the necessary ones with your own using the methods setCustom<NAME>FilePath.

Parameter setting example:

MRGSCOPPA.Instance.Parameters.DisableAccessForUnderagedUsers = true;

MRGSCOPPA.Instance.Parameters.SetCustomBirthdayFilePath("birthday_file_path");
MRGSCOPPA.Instance.Parameters.SetCustomEmailEnterFilePath("email_file_path");
MRGSCOPPA.Instance.Parameters.SetCustomCheckFilePath("check_file_path");
MRGSCOPPA.Instance.Parameters.SetCustomRestrictFilePath("restrict_file_path");
[MRGSCOPPA sharedInstance].parameters.disableAccessForUnderagedUsers = true;

[[MRGSCOPPA sharedInstance].parameters setCustomBirthdayFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_birthday" withExtension:@"html"]];
[[MRGSCOPPA sharedInstance].parameters setCustomEmailEnterFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_email" withExtension:@"html"]];
[[MRGSCOPPA sharedInstance].parameters setCustomCheckFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_check" withExtension:@"html"]];
[[MRGSCOPPA sharedInstance].parameters setCustomRestrictFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_restrict" withExtension:@"html"]];
MRGSCOPPA.getInstance().getParameters().setRestrictEnabled(true);

MRGSCOPPA.getInstance().getParameters().setBirthdayFile("birthday_file_path");
MRGSCOPPA.getInstance().getParameters().setEmailFile("email_file_path");
MRGSCOPPA.getInstance().getParameters().setCheckFile("check_file_path");
MRGSCOPPA.getInstance().getParameters().setRestrictFile("restrict_file_path");
Where should I put the custom HTML file?

For Unity:

The custom HTML file must be put in the mainBundle of the iOS application and in the assets of the Android one, specify only its name with the extension (or the relative path from the above directories) in the method. For example, myFile.html.
MRGSCOPPA.getInstance().Parameters.SetCustomEmailEnterFilePath("custom_coppa_email.html");

For iOS:

You can put the custom HTML file in any convenient place (usually in mainBundle), and transfer the full path to the file in NSURL format to the method. For example:

[[MRGSCOPPA sharedInstance].parameters setCustomEmailEnterFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_email" withExtension:@"html"]];
For Android:

In assets, specify only its name with the extension (or the relative path from the above directories) in the method. For example, "myFile.html".
MRGSCOPPA.getInstance().getParameters().setEmailFile("file_path");

How to properly make a custom HTML file?

We propose to take our standard agreement as a basis, it contains all the necessary elements and transitions. You can also download examples of our files from the link.

The most important thing to consider is the transition further when you press the button. When using a custom COPPA file, we understand that it is time to close the window and pull the callback of GET parameters by the presence of the checkboxAgree key in the query line after the button was pressed. Example: HTML/Path.html?checkboxAgree=on&checkboxContact=on. The easiest way to do this is by using a form - the standard mechanism allows you to add marked fields to GET. You can use our standard agreement file as a basis.

Please note that the accept button must be responsive (visually responsive to being clicked), otherwise the app may not be reviewed.

Important information for those who use COPPA without MRGSGDPR

If the project itself works with GDPR and does not send us information about the acceptance, then for COPPA to work correctly, you will need to do this - call the setUserHasAcceptedAgreementmethod. Also note that the version of the agreement is obtained from the MGS server, so if you have a different agreement from MyGames, you need to put the version on the MRGS website.

Step 3. Show window and Process the result🔗

Then use the method to display the agreement:

There are two methods for showing the agreement - one will give the result of the work to the delegate, and the other to the lambda function (block)(and also in the delegate, if set).

Getting the result in a lambda function:

MRGSCOPPA.Instance.ShowCOPPAFlowIfNeeded((result, error) =>
{
    if (error == null)
    {
        Debug.Log("COPPA finished with result - " + result);
    }
    else
    {
        Debug.Log("Failed to show COPPA flow with error - " + error);
    }
});
[[MRGSCOPPA sharedInstance] showCOPPAFlowIfNeededAtViewController:controller withCompletion:^(MRGSCOPPAShowResult * _Nonnull result, NSError * _Nonnull error) {
    if(!error){
        NSLog(@"COPPA finished with result - %@", result);
    }else{
        NSLog(@"Failed to show COPPA flow with error - %@",  error);
    }
}];
MRGSCOPPA.getInstance().showCoppaFlowIfNeed(activity, new MRGSCOPPA.OnShowResultCallback() {
    @Override
    public void onShowResult(@Nullable MRGSCOPPAShowResult result, @Nullable MRGSError error) {
        if (error == null) {
            Log.d("MRGSCOPPA", "Success.");
        } else {
            Log.d("MRGSCOPPA", "Failed to show coppa flow. Need to exit app.");
        }
    }
});

Getting the result to the delegate:

// 'this' conforms to 'MRGSCOPPA.IShowDelegate' protocol
MRGSCOPPA.Instance.Delegate = this;
MRGSCOPPA.Instance.ShowCOPPAFlowIfNeeded();

// ...
// Deleagte implementation
#region COPPA
public void OnFinishedCOPPAFlowWithResult(MRGSCOPPAShowResult result)
{
    Debug.Log("Delegate<Unity>: OnFinishedCOPPAFlowWithResult - " + result);
}

public void OnReceivedErrorWhileShowingCOPPAFlow(MRGSError error)
{
    Debug.Log("Delegate<Unity>: OnReceivedErrorWhileShowingCOPPAFlow - " + error);
}
#endregion
[MRGSCOPPA sharedInstance].delegate = self;
[[MRGSCOPPA sharedInstance] showCOPPAFlowIfNeededAtViewController:controller];

// ...
// Deleagte implementation
- (void)didFinishCOPPAFlowWithResult:(nonnull MRGSCOPPAShowResult *)showResult {
    NSLog(@"COPPA finished with result - %@", result);
}

- (void)didReceiveErrorWhileShowingCOPPAFlow:(nonnull NSError *)error {
    NSLog(@"Failed to show COPPA flow with error - %@",  error);
}
MRGSCOPPA.getInstance().setOnShowResultListener(this);
MRGSCOPPA.getInstance().showCoppaFlowIfNeed(activity);

// ...
// Deleagte implementation
@Override
void onShowFinished(@NonNull MRGSCOPPAShowResult result){
    // COPPA finished with result
}

@Override
void onShowFailed(@NonNull MRGSError error){
    // Failed to show COPPA flow with error
}

Important

You need to call the display method at each start of the application. If the user has already agreed to COPPA, or the window does not need to be shown, we will immediately call the delegate method. If the user has already accepted the last agreement, the delegate method will be called immediately on successful completion, that is, you do not need to do any checks, we will do everything for you.

Interop with GDPR🔗

If you use MRGSGDPR to display the user agreement and you want to use MRGSCOPPA, you need to take into account the basic logic - first COPPA(age selection) is shown, and then GDPR if necessary. Therefore, you need to show the COPPA process first, and then the GDPR.

If you use the GDPR display by our means, using HTML layout, then to enable the preview of the COPPA window, you just need to call methods:

// Setting COPPA
MRGSCOPPA.Instance.Parameters.DisableAccessForUnderagedUsers = true;
MRGSCOPPA.Instance.Parameters.SetCustomEmailEnterFilePath("custom_coppa_email.html");

MRGSGDPR.Instance.Setup("<PROJECT_ID>", "<PROJECT_SECRET>");
MRGSGDPRShowParams showParams = new MRGSGDPRShowParams
{
    AutomaticCoppaFlow = true
};
MRGSGDPR.Instance.ShowAgreement(showParams);
// Setting COPPA
MRGSCOPPA.Instance.Parameters.DisableAccessForUnderagedUsers = true;
MRGSCOPPA.Instance.Parameters.SetCustomEmailEnterFilePath("custom_coppa_email.html");

// Setting GDPR part
// ...
MRGSGDPR.getInstance().enableAutomaticCOPPAFlow(APP_ID, APP_SECRET);
// ...

// Showing GDPR
MRGSGDPR.getInstance().showDefaultAgreement(APP_ID);
// Setting COPPA
[MRGSCOPPA sharedInstance].parameters.disableAccessForUnderagedUsers = true;
[[MRGSCOPPA sharedInstance].parameters setCustomEmailEnterFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_email" withExtension:@"html"]];

[[MRGSGDPR sharedInstance] setupWithAppId:<PROJECT_ID> secret:@"<PROJECT_SECRET>"];
MRGSGDPRShowParams* showParams = [[MRGSGDPRShowParams alloc] init];
showParams.automaticCOPPAFlow = true;
[[MRGSGDPR sharedInstance] showAgreementAtViewController:self params:showParams];
// Setting COPPA
[MRGSCOPPA sharedInstance].parameters.disableAccessForUnderagedUsers = true;
[[MRGSCOPPA sharedInstance].parameters setCustomEmailEnterFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_email" withExtension:@"html"]];

// Setting GDPR part
// ...
[[MRGSGDPR sharedInstance] enableAutomaticCOPPAFlowForAppId:APP_ID andSecret:APP_SECRET];
// ...

// Showing GDPR
[[MRGSGDPR sharedInstance] showDefaultAgreementAtViewController:rootController forAppId:APP_ID];
MRGSGDPR.getInstance().showDefaultAgreement(APP_ID);
import android.app.Activity;

import games.my.mrgs.gdpr.MRGSGDPR;
import games.my.mrgs.gdpr.MRGSGDPRShowParams;

// Setting COPPA
MRGSCOPPA.getInstance().getParameters().setRestrictEnabled(true);
MRGSCOPPA.getInstance().getParameters().setEmailFile("file_path");

MRGSGDPR.getInstance().setup(Context, "<PROJECT_ID>", "<PROJECT_SECRET>");

final MRGSGDPRShowParams showParams = new MRGSGDPRShowParams();
showParams.setAutomaticCOPPAFlowEnabled(true);

MRGSGDPR.getInstance().showAgreement(Activity, showParams);
// Setting COPPA
MRGSCOPPA.getInstance().getParameters().setRestrictEnabled(true);
MRGSCOPPA.getInstance().getParameters().setEmailFile("file_path");

// Setting GDPR part
// ...
MRGSGDPR.MRGSGDPRFactory.getMRGSGDPR().enableAutomaticCOPPAFlow(APP_ID, APP_SECRET);
// ...

// Showing GDPR
MRGSGDPR.MRGSGDPRFactory.getMRGSGDPR().showDefaultAgreementAtActivity(activity, APP_ID);

If you use a completely custom window, you need to manually make a sequential call to COPPA and GDPR:

// COPPA setup
MRGSCOPPA.Instance.Setup(APP_ID, APP_SECRET);

// Setting COPPA
MRGSCOPPA.Instance.Parameters.DisableAccessForUnderagedUsers = true;
MRGSCOPPA.Instance.Parameters.SetCustomEmailEnterFilePath("custom_coppa_email.html");

// Showing COPPA
MRGSCOPPA.Instance.ShowCOPPAFlowIfNeeded((result, error) =>
{
    if (error == null)
    {
        // Showing GDPR flow
        <CURRENT_SHOW_GDPR_FLOW>
    }
    else
    {
        Debug.Log("Failed to show COPPA flow with error - " + error);
    }
});
// COPPA setup
[[MRGSCOPPA sharedInstance] setupForAppId:APP_ID andSecret:APP_SECRET];

// Setting COPPA
[MRGSCOPPA sharedInstance].parameters.disableAccessForUnderagedUsers = true;
[[MRGSCOPPA sharedInstance].parameters setCustomEmailEnterFilePath:[[NSBundle mainBundle] URLForResource:@"custom_coppa_email" withExtension:@"html"]];

// Showing COPPA
[[MRGSCOPPA sharedInstance] showCOPPAFlowIfNeededAtViewController:controller withCompletion:^(MRGSCOPPAShowResult * _Nonnull result, NSError * _Nonnull error) {
    if(!error){
        // Showing GDPR flow
        <CURRENT_SHOW_GDPR_FLOW>
    }else{
        NSLog(@"Failed to show COPPA flow with error - %@",  error);
    }
}];
// COPPA setup
MRGSCOPPA.getInstance().setUp(APP_ID, APP_SECRET);

// Setting COPPA
MRGSCOPPA.getInstance().getParameters().setRestrictEnabled(true);
MRGSCOPPA.getInstance().getParameters().setEmailFile("file_path");

// Showing COPPA
MRGSCOPPA.getInstance().showCoppaFlowIfNeed(activity, new MRGSCOPPA.OnShowResultCallback() {
    @Override
    public void onShowResult(@Nullable MRGSCOPPAShowResult result, @Nullable MRGSError error) {
        if (error == null) {
            // Showing GDPR flow
            <CURRENT_SHOW_GDPR_FLOW>
        } else {
            Log.d("MRGSCOPPA", "Failed to show coppa flow. Need to exit app.");
        }
    }
});

Last update: 2025-01-21
Created: 2020-02-05