GDPR Compliance

fwiw, wip, use if/as you see fit, no license, released to PD…

-- main.lua, testbed for gdprutil.lua local gdprutil = require("gdprutil") gdprutil.verbose = true -- optionally print("No argument form:", gdprutil.isEUCountry()) print("Hardcoded pos DE:", gdprutil.isEUCountry("DE")) print("Hardcoded neg US:", gdprutil.isEUCountry("US")) print("Hardcoded blank:", gdprutil.isEUCountry("")) print("Hardcoded invalid:", gdprutil.isEUCountry({})) print("Manual getpref():", gdprutil.isEUCountry(system.getPreference("locale","country","string")))

-- gdprutil.lua local M = {} M.name = "gdprutil" M.version = "0.1" M.verbose = false -- References: -- https://en.wikipedia.org/wiki/Member\_state\_of\_the\_European\_Union -- https://www.iso.org/iso-3166-country-codes.html -- https://en.wikipedia.org/wiki/ISO\_3166-1 M.EUCountryCodeList = { ["AT"] = "Austria", ["BE"] = "Belgium", ["BG"] = "Bulgaria", ["HR"] = "Croatia", ["CY"] = "Cypress", ["CZ"] = "Czechia", -- aka "Czech Republic" ["DK"] = "Denmark", ["EE"] = "Estonia", ["FI"] = "Finland", ["FR"] = "France", ["DE"] = "Germany", ["GR"] = "Greece", ["HU"] = "Hungary", ["IE"] = "Ireland", ["IT"] = "Italy", ["LV"] = "Latvia", ["LT"] = "Lithuania", ["LU"] = "Luxembourg", ["MT"] = "Malta", ["NL"] = "Netherlands", ["PL"] = "Poland", ["PT"] = "Portugal", ["RO"] = "Romania", ["SK"] = "Slovakia", ["SI"] = "Slovenia", ["ES"] = "Spain", ["SE"] = "Sweden", ["GB"] = "United Kingdom", } --- -- Tests if the given country code represents an EU member country -- @param country String Optional The two-character ISO 3166-1 country code -- if not provided, and running in Corona SDK environment, will look up value from system -- @return Boolean -- True if country code represents an EU member country -- False if country code does not represent an EU member country, or could not be determined -- M.isEUCountry = function(country) --------------------------------------- -- handle default value (if Corona SDK) --------------------------------------- if (not country) then if ((type(system)=="table") and (type(system.getPreference)=="function")) then country = system.getPreference("locale", "country", "string") end end --------------------------------------- -- handle missing/invalid values --------------------------------------- if (type(country) ~= "string") then if (M.verbose) then print("gdprutil.isEUCountry(): Invalid Country Code, result = false") end return false end --------------------------------------- -- perform lookup --------------------------------------- local result = M.EUCountryCodeList[country] ~= nil if (M.verbose) then print("gdprutil.isEUCountry(): Country Code '" .. country .. "', result = " .. tostring(result)) end return result end return M

@davebollinger, do you have this code on GitHub or some other site I can link to, instead of trying to point people to page 6 of this forum thread?

Thanks

Rob

@Rob:  https://github.com/davebollinger/gdprutil

at present it’s identical to the code above, except with an MIT license, because 1) the pd statement above isn’t adequate, and 2) to carry a disclaimer - so essentially still do whatever you want with it, just don’t “blame” me for it.  :smiley:

Can anyone please tell me. Is there a way to get non personalized Ads using Admob plugin. Also say i have Advertising Id then how to use that to remove user data from Admob servers

No. Not with the current plugin. Although the version of Admob that the plugin is using accepts the “extras” flag there is no mechanism to attach that value to the request from corona.

For the second item, I think you just send it to their support e-mail if they don’t have one set up for GDPR yet.

@davebollinger and @Rob, do you think it is enough to only look for “locale” & “country” values? Are they reliable sources of information?
For example, as an EU citizen what happens if I buy a phone from a non-EU country(e.g. Turkey or Australia) and bring it back to EU soil and start using it here? What values would I get from “locale” & “country”? Are those values constantly updated by iOS / Android / Fire OS upon each connection?

@bgmadclown:  no, it’s not perfect, but it’s all you’ve got… probably… unless you have access to an IP lookup service, etc - see Per’s writeup above.

would you rather pop up a dialog and ask them if they’re in the EU?  could you trust THAT response?? (for legal purposes)

only time-will-tell if implementation/enforcement allows for any sort of “best efforts vs technical limitation/difficulty” -type defense, i’m no lawyer.

for my own purposes, i’ve decided against trying a similar approach with locale because the “generic” language versions (fe “en”, “fr”, et al) are still valid, and would seem to pose even MORE trouble than the ones that directly correspond to their origin countries (fe “en_GB” vs “en_US”, or “fr_FR” vs “fr_CA”) given that “en” and “fr” (et al) are spoken in all sorts of varied countries.

but also, for my own purposes, i’ll be using it only as an additional measure, fe i’ll have already sanitized all analytics regardless of EU status.

@bdmadclown. Based on what Appodeal is saying here: https://www.appodeal.com/home/gdpr/

Do I have to request a consent only from EU users?

As the global privacy laws change, we recommend to request a consent from all users once, no matter where they are currently located. That will eliminate mistakes of not collecting consent from EU residents who are on a vacation elsewhere, for example.

We are going to follow a similar recommendation.

You can’t rely on IP address because they could be traveling. They could be using VPNs. As for Dave’s code above, I think it’s a great start, but the end user can fully control all those locale settings on their device. I could be living in Paris and have my phone setup with a country code of US.

So what should you do? That’s up to you. The safest thing is to ask everyone. This is getting into legal advice and you would be best to discuss what’s best for you with your lawyer.

With regards to AdMob. Google has everyone scratching their head on this one.  This article does a good job of explaining the chaos:

https://www.theregister.co.uk/2018/05/15/android_ad_pause_gdpr_chaos/

There is also a good article on consent from the Great Britain Information Commissioners office.

https://ico.org.uk/for-organisations/guide-to-the-general-data-protection-regulation-gdpr/lawful-basis-for-processing/consent/

They point out that you should not pre-check boxes, so if you add a widget.newSwitch() to your dialog box, it needs to default to off.

Rob

I think I’ll wait till there’s a solution for the Admob plugin before I rebuild and submit all of my apps for iOS/Google/Amazon with the latest Corona version.  That will likely be after May 25, but I don’t want to start doing it now with the new Corona build and then have to do it again once Google’s new AdMob plugin comes out.

For the sake of sharing here is what my screens for GDPR look like. The wording might change and I want to make the checkbox more visible. It is probably not 100% compliant, but as good as I will be able to get it without a lawyer. I am just waiting for Appodeal to update their plugin and I’ll publish it. 2 done. 3 more apps to go.

Just to make sure, because no one has ever mentioned it:

If I don’t want to show a consent screen, because it is ugly and obtrusive, is it a valid solution to

1) just give the parameter of [did not give consent] to Appodeal, or 

2) showing your own ads for your own games?

Thanks vlads. 

Yes philipp3 if you don’t have anything else to request consent for you can just send the tag “did not consent” to appodeal or just show your own internal ads.

… and what about the “right to be forgotten”?

let’s use Appodeal as an example, since they seem to be the furthest implemented yet…

let’s say dev pops a consent form, the user agrees, dev stores that consent record, and dev also provides a mechanism for later withdrawing consent (as also required).

then let’s say user later does withdraw consent, and further, user contacts dev asking that they be “forgotten”.  dev now has 30 days to reply/comply.

Appodeal’s own privacy policy indicates that they may have collected ip’s, device id’s, advertising id’s, etc.  GDPR appears to classify these as personally identifiable information.  So how would dev (on behalf of user, or the user themselves directly) then request that Appodeal expunge their records of that user?

ty

@devebollinger for now when you click on the contact us icon, I place both the IDFA (or the android Id) and my gamesparks Id in the body of the e-mail. I’ll just forward the request to appodeal or onesignal or run my script on the gamesparks id to wipe everything out.

Thank you!

It might be worth asking Appodeal about this directly. I’ve only seen talk about sending a no consent value that turns off targeted ads.

Rob

@rob I think we are talking about the same thing. Any idea when the new plugin will be out?

My App game is pay to play only. I only use the analytics from the stores(Apple/Google/Amazon) to see how it is selling and answer my rating feedback.

So to be clear, I do not need to do any of this outside of my own privacy Terms of Service since I use zero plug-ins for Ads or even Marketplace code? 

I personally haven’t followed what Apple and Google are requiring as far as GDPR. I don’t know if you have to ask for permission from them or not. The Apple data seems to be tracking installs and probably doesn’t need any personal data to count sales and downloads. Google seems to collect more data, but I don’t know that they need personal information to do it.

I’m not a lawyer so I can’t offer legal advice, but if Apple and Google are not telling you to ask for permission, you probably don’t. 

Rob