A mailer, member database, and so much more, for digital activism.
If you are unfamiliar with how Identity (and Speakout) represent and configure consents, it is recommended that you read the documentation on User Consent in these systems before proceeding:
This document runs through the process of updating Consents. This is easiest through a more concrete example, so for the purposes of this document we will assume an organisation has two primary consents:
In this document we will tackle how to update both of these, dealing with the changes required in Identity, Speakout, and Controlshift (if you are using Controlshift).
Important Note: The exact consents required by organisations will be different. What follows is just an example for demonstration. There may be specific legislation which you need to consider regarding the method of consent required for data processing and/or communicating with users, and how this consent must be stored. You should satisfy yourself that the method of obtaining and storing consent in Identity, Speakout & Controlshift meets the legal requirements of your jurisdiction before you proceed!
First, you will need to publish your new privacy policy on your website. In order to accurately track exactly which version of a privacy policy each user has seen and (implicitly) consented to while taking action, the recommended approach is to use versioned / dated links, eg:
This means that when a user submits data we can track the privacy policy version they were linked to.
For any areas of your website which link to your Privacy Policy, but are not tracked, it is recommended to use a
generic privacy-policy
link, which forwards to the latest version of the policy. Eg. you may include a link to
the privacy policy in the footer of your website, etc.
Step 1: Create a new ConsentText
object in Identity’s Ruby console using the template below. Note this is
a template only, the exact consent text will depend on your organisation. If you are only making changes to the
legal text of your privacy policy, you will most likely want to use the same consent_short_text
as your active
privacy policy, and update the link to the new version of the legal text.
ConsentText.create!(
public_id: 'privacy-policy-17-02-20',
consent_short_text: 'I consent to the <a href="https://{ your website }/privacy-policy-17-02-20" target="_blank">privacy policy</a>',
full_legal_text_link: 'https://{your_website}/privacy-policy-17-02-20'
)
Normally, simply agreeing to an organisations privacy policy will not have any immediate effect (such as subscribing
the user to a mailing list, etc). It is simply something which needs to be recorded for legal reasons. Therefore, no
PostConsentMethod
records are normally required when setting up or updating a privacy policy.
Step 1: Create the same ConsentText
object in Speakout’s Padrino console. It is critical that you use EXACTLY the same
public_id, consent text wording, and link in both Identity & Speakout, otherwise what is displayed to the user in Speakout,
and what is stored in the Identity CRM will not match!
ConsentText.create!(
public_id: 'privacy-policy-17-02-20',
consent_short_text: 'I consent to the <a href="https://{ your website }/privacy-policy-17-02-20" target="_blank">privacy policy</a>',
full_legal_text_link: 'https://{your_website}/privacy-policy-17-02-20'
)
Step 2: Update the default privacy policy used by your org in Speakout. There are multiple ways to do this.
Different configurations for displaying consent are stored in the ConsentConfiguration
table. Check if your org is
using this table for it’s default configuration by running this on the Padrino Console:
ConsentConfiguration.where(default_consent: true)
If a record is returned, you should either update your existing default ConsentConfiguration
record to use the new
privacy policy, or you may wish to create a new ConsentConfiguration
using the new privacy policy, and set this as
the default (setting default_consent
to false
on the old record).
If no record is returned, and your org has consent configuration stored in your Settings file (usually named
settings.YOUR-ORG-NAME.yml
), then it is easiest to simply amend your Settings file with the new privacy policy
public_id
. Once amended, you will need to deploy the new Speakout code to your Production Speakout instance.
Either way, you should consult the Speakout Documentation on Consent Configurations for guidance on the exact JSON/yaml to use to configure your default consent configuration appropriately.
Note, if you have both a default ConsentConfiguration
record, and consents setup in your Settings file, the
ConsentConfiguration
database record takes precedence.
Step 3: Validate your Speakout -> Identity Consent setup.
First, check Speakout is displaying your new Privacy Policy wording (the consent_short_text
) on campaigns.
Then, validate that when taking a Speakout action, the action & consent data is sync’d to Identity as expected. The
following SQL can be used against the Identity database to verify this. Ensure the
member_action_consent.consent_text_id
links to your new privacy policy ConsentText
:
SELECT mac.*
FROM member_action_consents mac
JOIN member_actions ma ON mac.member_action_id = ma.id
JOIN members m ON ma.member_id = m.id
WHERE m.email = '<email_you_signed_with>'
AND ma.created_at > '<todays_date>';
If you also use ControlShift, you will probably want to update the Privacy Policy used on the ControlShift platform as well.
Login to your ControlShift instance, and visit: https://{your_controlshift_site}/org/consent_content_versions
You will see a table of ‘Consent Versions’. Consent Versions in ControlShift consist of a combination of a version of the Privacy Policy, the Terms of Service, and the Data Processing Consent Label. If you have updated your Privacy Policy, this likely means you need to update two things:
Unfortunately, as soon as either of these is updated, the change goes live, and a new ‘Consent Version’ is immediately created. There is no way to ‘atomically’ update both the Privacy Policy and the Data Processing Consent Label, meaning if both need updating, you will always have a middle ‘junk’ Consent Version created.
Step 1: Update the “Data Processing Consent Label” by clicking the current version in the ControlShift UI, and
editing the text as necessary. It is critical that you use EXACTLY the same wording here as you used for the
ConsentText.consent_short_text
in Identity, otherwise what is displayed to the user on ControlShift, and what is
stored in the Identity CRM will not match!
Step 2: Update the “Privacy Policy” by clicking the current version in the Controlshift UI, and editing the text as necessary. It should match the privacy policy published on your website (eg. the text at https://{your_website}/privacy-policy-17-02-20 )
Step 3: Add external_id
labels to the new ‘Consent Versions’ in the Controlshift UI. It is recommended that
you name these to match your ConsentText.public_id
- but since you may have multiple ‘Consent Versions’ in
Controlshift which map to a single ConsentText
, you may want to add -v1
, -v2
, etc. In the above example,
editing both the “Data Processing Consent Label” and “Privacy Policy” would result in 2 new ‘Consent Versions’, so
we would name them privacy-policy-17-02-20-v1
and privacy-policy-17-02-20-v2
.
Step 4: Link the new ControlShift ‘Consent Versions’ to the correct ConsentText
in Identity.
To do this, we must create a ControlshiftConsent
record, and a ControlshiftConsentMapping
record, for each new
‘Consent Version’ in Controlshift (in this case, two new versions were created). A ControlshiftConsent
record is
simply Identity’s model of a ‘Consent Version’ in the ControlShift platform, while ControlshiftConsentMapping
records link a single ControlshiftConsent
to one or more ConsentText
, including data about how a user opted in or
out.
In the Identity Rails Console, run the following:
cc_v1 = ControlshiftConsent.find_or_create_by!(
controlshift_consent_type: 'consent_content_version',
controlshift_version_id: FIND_ME_IN_THE_CSL_UI,
controlshift_consent_external_id: 'privacy-policy-17-02-20-v1'
)
ControlshiftConsentMapping.create!(
controlshift_consent_id: cc_v1.id,
consent_text: ConsentText.find_by(public_id: 'privacy-policy-17-02-20'),
method: "implicit",
opt_in_level: "implicit",
opt_in_option: "",
opt_out_level: "none_given",
opt_out_option: ""
)
cc_v2 = ControlshiftConsent.find_or_create_by!(
controlshift_consent_type: 'consent_content_version',
controlshift_version_id: FIND_ME_IN_THE_CSL_UI,
controlshift_consent_external_id: 'privacy-policy-17-02-20-v2'
)
ControlshiftConsentMapping.create!(
controlshift_consent_id: cc_v2.id,
consent_text: ConsentText.find_by(public_id: 'privacy-policy-17-02-20'),
method: "implicit",
opt_in_level: "implicit",
opt_in_option: "",
opt_out_level: "none_given",
opt_out_option: ""
)
Step 5: Validate your ControlShift -> Identity Consent setup.
First, check ControlShift is displaying your new “Data Processing Consent Label” on campaigns (which should match the
ConsentText.consent_short_text
value for your updated Privacy Policy).
Then, validate that when taking a ControlShift action, the action & consent data is sync’d to Identity as expected. The
following SQL can be used against the Identity database to verify this. Note, ControlShift actions may take a few
minutes to sync across to Identity. Ensure the member_action_consent.consent_text_id
links to your new privacy policy
ConsentText
:
SELECT mac.*
FROM member_action_consents mac
JOIN member_actions ma ON mac.member_action_id = ma.id
JOIN members m ON ma.member_id = m.id
WHERE m.email = '<email_you_signed_with>'
AND ma.created_at > '<todays_date>';
Step 1: Create a new ConsentText
object in Identity’s Ruby console as follows:
ConsentText.create!(
public_id: 'contact-consent-17-02-20',
consent_short_text: 'Do you agree to being contacted about this & other important campaigns? You can unsubscribe anytime.',
full_legal_text_link: ''
)
Step 2: Create appropriate PostConsentMethod
records in Identity’s Ruby Console.
Since agreeing to this new ConsentText
should subscribe a user, and disagreeing should unsubscribe the user, we also
need PostConsentMethod
records to carry this out:
PostConsentMethod.create!(
consent_text: ConsentText.find_by(public_id: 'contact-consent-17-02-20'),
min_consent_level: 1,
max_consent_level: 1,
method: 'email_unsubscribe'
)
PostConsentMethod.create!(
consent_text: ConsentText.find_by(public_id: 'contact-consent-17-02-20'),
min_consent_level: 4,
max_consent_level: 4,
method: 'email_subscribe'
)
In this case, we’re configuring Identity to call the email_unsubscribe
method if a user gives a consent_level
of 1
(None Given), and call the email_subscribe
method if a user gives a consent_level
of 4
(Explicit Opt-In). More
information about the different levels of consent is available
here.
Step 1: Create the same ConsentText
object in Speakout’s Padrino console. It is critical that you use EXACTLY the same
wording in Identity & Speakout, otherwise what is displayed to the user, and what is stored in the Identity CRM will
not match!
ConsentText.create!(
public_id: 'contact-consent-17-02-20',
consent_short_text: 'Do you agree to being contacted about this & other important campaigns? You can unsubscribe anytime.',
full_legal_text_link: ''
)
Step 2: Update the default contact consent used by your org in Speakout. There are multiple ways to do this.
Different configurations for displaying consent are stored in the ConsentConfiguration
table. Check if your org is
using this table for it’s default configuration by running this on the Padrino Console:
ConsentConfiguration.where(default_consent: true)
If a record is returned, you should either update your existing default ConsentConfiguration
record to use the new
contact consent, or you may wish to create a new ConsentConfiguration
using the new contact consent, and set this as
the default (setting default_consent
to false
on the old record).
If no record is returned, and your org has consent configuration stored in your Settings file (usually named
settings.YOUR-ORG-NAME.yml
), then it is easiest to simply amend your Settings file with the new contact consent
public_id
. Once amended, you will need to deploy the new Speakout code to your Production Speakout instance.
Either way, you should consult the Speakout Documentation on Consent Configurations for guidance on the exact JSON/yaml to use to configure your default consent configuration appropriately.
Note, if you have both a default ConsentConfiguration
record, and consents setup in your Settings file, the
ConsentConfiguration
database record takes precedence.
Step 3: Validate your Speakout -> Identity Consent setup.
First, check Speakout is displaying your new Email Contact Consent wording (the consent_short_text
) on campaigns,
and that it has the expected method of consenting (eg. a checkbox, radio buttons, etc).
Then, validate that when taking a Speakout action, the action & consent data is sync’d to Identity as expected. The
following SQL can be used against the Identity database to verify this. Ensure the
member_action_consent.consent_text_id
links to your new contact consent ConsentText
, and that the consent_level
is accurate, depending on whether you opted in or not:
SELECT mac.*
FROM member_action_consents mac
JOIN member_actions ma ON mac.member_action_id = ma.id
JOIN members m ON ma.member_id = m.id
WHERE m.email = '<email_you_signed_with>'
AND ma.created_at > '<todays_date>';
Finally, validate that the member subscription record has been updated appropriately. It is recommended you take action multiple times, perhaps with multiple emails, to verify both the opt-in and opt-out path are working correctly:
SELECT ms.*
FROM member_subscriptions ms
JOIN members m ON ms.member_id = m.id
WHERE m.email = '<email_you_signed_with>';
If you also use ControlShift, you will probably want to update the Email Opt-In Type used on the ControlShift platform as well.
Step 1: Create a new Email Opt In Type.
Login to your ControlShift instance, and visit: https://{your_controlshift_site}/org/email_opt_in_types
We are interested in updating the Active Web Form, so click on ‘Update’ next to this.
Select the type of behaviour you want to use to obtain consent (eg. ‘Pre-checked checkbox’, ‘Radio Buttons’, etc) and
update the text fields below. It is critical that you use EXACTLY the same wording for the “Web Form Email Opt-in
Label” as you used for the ConsentText.consent_short_text
in Identity, otherwise what is displayed to the user on
ControlShift, and what is stored in the Identity CRM will not match!
If using Radio Buttons, you should also ensure that the “Radio Opt In Yes Label” and “Radio Opt In No Label” also match the radio button labels you used in Speakout, although these can be configured appropriately later if they do not match.
Step 2: Ensure the new Email Opt In Type has an external_id
. These can be set by visiting
https://{your_controlshift_site}/org/email_opt_in_types/advanced - it is recommended that you name this to match your
ConsentText.public_id
, so we would name it contact-consent-17-02-20
.
Step 3: Link the new ControlShift ‘Email Opt-In Type’ to the correct ConsentText
in Identity.
To do this, we must create a ControlshiftConsent
record, and a ControlshiftConsentMapping
record, for each new
‘Email Opt-In Type’ in Controlshift. A ControlshiftConsent
record is simply Identity’s model of an ‘Email Opt-In Type’
in the ControlShift platform, while ControlshiftConsentMapping
records link a single ControlshiftConsent
to one or
more ConsentText
, including data about how a user opted in or out.
Assuming you used Radio Buttons in the ControlShift UI, run the following in the Identity Rails Console:
cc = ControlshiftConsent.find_or_create_by!(
controlshift_consent_type: 'email_opt_in_type',
controlshift_version_id: FIND_ME_IN_THE_CSL_UI,
controlshift_consent_external_id: 'contact-consent-17-02-20'
)
ControlshiftConsentMapping.create!(
controlshift_consent_id: cc.id,
consent_text: ConsentText.find_by(public_id: 'contact-consent-17-02-20'),
method: "csl_radio_buttons",
opt_in_level: "explicit_opt_in",
opt_in_option: "THIS TEXT SHOULD MATCH THE 'Radio Opt In Yes Label'",
opt_out_level: "none_given",
opt_out_option: "THIS TEXT SHOULD MATCH THE 'Radio Opt In No Label'"
)
Step 4: Validate your ControlShift -> Identity Consent setup.
First, check ControlShift is displaying your new “Email Opt-In Type” on campaigns (which should match the
ConsentText.consent_short_text
value for your new contact consent wording).
Then, validate that when taking a ControlShift action, the action & consent data is sync’d to Identity as expected. The
following SQL can be used against the Identity database to verify this. Note, ControlShift actions may take a few
minutes to sync across to Identity. Ensure the member_action_consent.consent_text_id
links to your new contact consent
ConsentText
:
SELECT mac.*
FROM member_action_consents mac
JOIN member_actions ma ON mac.member_action_id = ma.id
JOIN members m ON ma.member_id = m.id
WHERE m.email = '<email_you_signed_with>'
AND ma.created_at > '<todays_date>';
Finally, validate that the member subscription record has been updated appropriately. It is recommended you take action multiple times, perhaps with multiple emails, to verify both the opt-in and opt-out path are working correctly:
SELECT ms.*
FROM member_subscriptions ms
JOIN members m ON ms.member_id = m.id
WHERE m.email = '<email_you_signed_with>';