The CampaignSignUpHelper library intends to simplify integration with the GivePenny campaign sign-up APIs.
The library is currently intended to be used via browsers, for example from custom campaign sign-up sites:
<script src="https://assets.givepenny.com/gp-campaign-sign-up-helper.umd.js"></script>The built UMD module targets ECMAScript 2015 (ES6). See browser support on Caniuse.com.
Once installed, the built UMD module is available on window via window.GPCampaignSignUpHelper. The module exposes a class CampaignSignUpRequest, which should be instantiated for each new campaign sign-up.
Note that the identifiers in the following code snippet are examples only, and should be replaced with real identifiers. See Development Helper below for detail on retrieving identifiers for a campaign.
const charityId = "dc3ee97f-f307-45fa-a808-435144eca3fe";
const campaignId = "288c0223-2d78-4460-9ade-afd67eaeb9fb";
const campaignSignUpRequest = new window
.GPCampaignSignUpHelper
.CampaignSignUpRequest(
charityId,
campaignId
);Once constructed, the campaignSignUpRequest may be enriched with further information about the sign-up request, for example:
The first name of the person requesting to sign up to the campaign can be set using setFirstName, and later retrieved using the firstName getter.
setFirstName takes a single string argument.
// Assuming validation has already been carried out
const firstName = document.querySelector("#first-name-input").value;
campaignSignUpRequest.setFirstName(firstName);
// ...
document.querySelector("#thank-you-message").innerText =
"Thank you for signing up, " +
campaignSignUpRequest.firstName +
"!";Note that setFirstName will throw an error if the value is falsy (e.g. "").
The last name of the person requesting to sign up to the campaign can be set using setLastName, and later retrieved using the lastName getter.
setLastName takes a single string argument.
// Assuming validation has already been carried out
const lastName = document.querySelector("#last-name-input").value;
campaignSignUpRequest.setLastName(lastName);Note that setLastName will throw an error if the value is falsy (e.g. "").
The email address of the person requesting to sign up to the campaign can be set using setEmail, and later retrieved using the email getter.
This value will be used to contact the person signing up with a link to complete their sign-up. The sign-up API will fail validation if this value is not in a valid email format. It should be ensured that a valid email address is provided when setEmail is called (e.g. by using an HTML input with type="email"). For more information, please see the documented outcomes of the PutSignUpRequest Operation.
setEmail takes a single string argument.
// Assuming validation has already been carried out
const email = document.querySelector("#email-input").value;
campaignSignUpRequest.setEmail(email);
// ...
document.querySelector("#thank-you-message").innerText =
"Please look out for an email in your " +
campaignSignUpRequest.email +
" inbox with a link to complete your sign-up!";Note that setEmail will throw an error if the value is falsy (e.g. "").
Once enriched with at least firstName, lastName and email, the sign-up request may be submitted, for example:
campaignSignUpRequest
.submit()
.then(() => {
// The sign-up request has been submitted
// Safe to proceed to e.g. show a thank you message
})
.catch(() => {
// There was an error when submitting the sign-up request
});submit takes no arguments, and returns a Promise which is resolved with no value.
After the sign-up has been submitted, further calls to any of its methods will result in an error being thrown (getters may still be accessed).
While only firstName, lastName and email are required in order for the sign-up request to be submitted, the CampaignSignUpRequest class supports capture of further information:
Charity marketing opt-in may be captured on the campaignSignUpRequest using setIsOptedInToMarketing, and later retrieved using the isOptedInToMarketing getter.
setIsOptedInToMarketing takes a single boolean parameter.
// Assuming validation has already been carried out
const isOptedInToMarketing =
document.querySelector("#marketing-opt-in-input").checked;
campaignSignUpRequest.setIsOptedInToMarketing(
isOptedInToMarketing
);Options to be used when the person signing up completes their sign-up and launches their fundraising challenge may be captured on the campaignSignUpRequest using setChallengeActivity and setChallengeMusicPlaylist. These can be later retrieved using the challengeOptions getter.
Note that the identifiers in the following code snippets are examples only, and should be replaced with real identifiers. See Development Helper below for detail on retrieving activity identifiers for a campaign.
The setChallengeActivity method takes two arguments: GUID string activityId, GUID string measurementId. It also accepts an optional third number argument activityTarget.
Example without activityTarget:
const activityId = "528fb77f-1552-4543-95e0-17576b0d5029";
const measurementId = "da94980c-f29f-43c8-953b-8bb2375b8231";
campaignSignUpRequest.setChallengeActivity(
activityId,
measurementId
);Example with activityTarget:
const activityId = "528fb77f-1552-4543-95e0-17576b0d5029";
const measurementId = "da94980c-f29f-43c8-953b-8bb2375b8231";
// Assuming validation has already been carried out
const activityTarget = Number(
document.querySelector("#activity-target-select").value
);
campaignSignUpRequest.setChallengeActivity(
activityId,
measurementId,
activityTarget
);Note that setChallengeActivity will throw an error if activityId or measurementId are falsy (e.g. ""). An error will also be thrown if an activityTarget is provided and is negative or NaN.
The setChallengeMusicPlaylist method takes a single boolean argument.
const challengeMusicPlaylistEnabled =
document.querySelector("#enable-challenge-music-playlist").checked;
campaignSignUpRequest.setChallengeMusicPlaylist(
challengeMusicPlaylistEnabled
);Group selections for campaign groupings may be captured on the campaignSignUpRequest using setGroup, and later retrieved using the groups getter. For more information on groupings, please see the Challenge Groupings Service API documentation.
Note that the identifiers in the following code snippets are examples only, and should be replaced with real identifiers. See Development Helper below for detail on retrieving grouping identifiers for a campaign.
The setGroup method takes two GUID string arguments: groupingId and groupId.
const groupingId = "25936cfe-a4bb-4dec-868e-e07ae6763e33";
const groupId = "2020bd47-7aef-4221-a113-6bc9e7ecdc56";
campaignSignUpRequest.setGroup(
groupingId,
groupId
);The groups getter returns an array of objects containing keys groupingId and groupId, e.g.:
[
{
groupingId: "25936cfe-a4bb-4dec-868e-e07ae6763e33",
groupId: "2020bd47-7aef-4221-a113-6bc9e7ecdc56",
}
]Note that setGroup will throw an error if groupingId or groupId are falsy (e.g. "").
Additional miscellaneous questions & answers may be captured on the campaignSignUpRequest using setAdditionalQuestion. These may later be retrieved using the additionalQuestions getter. For more information on these additional questions, please see the PatchSignUpQuestions API Operation documentation.
The setAdditionalQuestion method takes two string arguments: question and answer.
const question = "Where did you hear about the campaign?";
// Assuming validation has already been carried out
const answer =
document.querySelector("#sign-up-source-select").value;
campaignSignUpRequest.setAdditionalQuestion(
question,
answer
);Note that setAdditionalQuestion will throw an error if question is falsy (e.g. ""). An empty string answer is valid. Furthermore, question values may not be longer than 100 characters, and at most 30 different questions may be set.
The additionalQuestions getter returns an object containing keys for added questions with values set to their answers, e.g. from the above code snippet:
{
"Where did you hear about the campaign?":
"Social media"
}In addition to the submit method, CampaignSignUpRequest exposes a sendData method. This method allows the current state of the CampaignSignUpRequest to be sent to the API without marking the request as having been submitted. This allows for data to be saved at more frequent intervals, e.g. after each step of a multi-step form. Ultimately this can be used to aid in reporting of incomplete sign-up requests (those where the person signing up abandoned the process part way through).
sendData takes no arguments, and returns a Promise which is resolved with no value.
campaignSignUpRequest
.sendData()
.then(() => {
// The sign-up request data has been sent to the API
})
.catch(() => {
// There was an error when sending the sign-up request data to the API
});constructor(charityId, campaignId)charityIdparameter is of typestring(GUID)campaignIdparameter is of typestring(GUID)
signUpIdgetter - returns a GUIDstringcharityIdgetter - returns a GUIDstringcampaignIdgetter - returns a GUIDstringsetFirstName(firstName)firstNameparameter is of typestring
firstNamegetter - returns astringsetLastName(lastName)lastNameparameter is of typestring
lastNamegetter - returns astringsetEmail(email)emailparameter is of typestring
emailgetter - returns astringsetGroup(groupingId, groupId)groupingIdparameter is of typestring(GUID)groupIdparameter is of typestring(GUID)
groupsgetter - returns an array of{ groupingId: string, groupId: string }setAdditionalQuestion(question, answer)questionparameter is of typestringanswerparameter is of typestring
additionalQuestionsgetter - returns anobject(withquestionkeys and values as theiranswers)setChallengeActivity(activityId, measurementId)activityIdparameter is of typestring(GUID)measurementIdparameter is of typestring(GUID)
setChallengeActivity(activityId, measurementId, activityTarget)activityIdparameter is of typestring(GUID)measurementIdparameter is of typestring(GUID)activityTargetparameter is of typenumber
setChallengeMusicPlaylist(challengeMusicPlaylistEnabled)challengeMusicPlaylistEnabledparameter is of typeboolean
challengeOptionsgetter - returns anobjectwith keysactivityId,measurementId,activityTarget,musicPlaylistsetIsOptedInToMarketing(isOptedInToMarketing)isOptedInToMarketingparameter is of typeboolean
isOptedInToMarketinggetter - returns abooleansendData()- returns aPromisesubmit()- returns aPromise
- The
campaignSignUpRequestshould only be modified using itsset...methods, mutating values retrieved from getters will not update the actual value on thecampaignSignUpRequest- E.g.
campaignSignUpRequest.challengeOptions.musicPlaylist = true;will not work, andcampaignSignUpRequest.setChallengeMusicPlaylist(true)should be used instead
- E.g.
setGroupandsetAdditionalQuestionmay be called multiple times with the samegroupingIdorquestionto update the selectedgroupIdoranswerrespectively- Across all
set...methods, once a value has been set it may be changed, but may not be unset- E.g.
setFirstName("Alice"); setFirstName("Bob");is fine, whilesetFirstName("Alice"); setFirstName(undefined);is not supported - Likewise for
setGroupandsetAdditionalQuestion, there are noremoveGrouporremoveAdditionalQuestioncounterpart methods
- E.g.
- After the sign-up has been submitted, further calls to any of its methods will result in an error being thrown (getters may still be accessed)
Bundled in the UMD module is a second helper function getCampaignDetails. This function accepts a single string argument, which is the URL slug of the campaign (e.g. from a campaign URL https://givepenny.com/campaign/{slug}).
The getCampaignDetails function returns a Promise which is resolved with an object containing identifiers and display labels for details about the campaign that may be useful at sign-up time.
This includes the campaign name & ID and the charity ID. Also included are the groupings for the campaign (if any have been configured, see the Challenge Groupings Service API documentation for more detail), and details around the activities being measured by the campaign (again, if any).
Example of the resolved value from a call to this function:
{
"name": "Example campaign",
"campaignId": "246213c7-2f08-4b2d-8c63-afebdf5c3a90",
"charityId": "ebf54844-5d67-455c-aafa-6cdfd9ed35c5",
"measuring": [
{
"measurementId": "65e12b09-0610-4ec8-886e-7ba7447523e7",
"preferredUnitId": "dc555699-754e-4d34-a512-eeb4ca2dfbab",
"activities": [
{
"activityId": "2471718b-62ba-4dfc-9b4b-24ef0cd2514d",
"targets": [{ "target": 1000 }],
"activityName": "Moving"
},
{
"activityId": "528fb77f-1552-4543-95e0-17576b0d5029",
"targets": [{ "target": 1000 }],
"activityName": "Running"
}
],
"measurementName": "Duration",
"preferredUnitName": "Minutes"
}
],
"groupings": [
{
"id": "7ba0a276-6adb-4e80-ab6d-2c97c0421e02",
"label": "Team",
"groups": [
{
"id": "7ee084c7-5c29-408e-9c14-41df3123e489",
"label": "Team 1"
},
{
"id": "a627d8cb-f8cd-40ee-b18c-db64258367b8",
"label": "Team 2"
}
]
}
]
}Some of the APIs used by this helper function are restricted to GivePenny origins by their CORS policies, so the helper has been made available on our documentation site:
Use the Development Helper on the GivePenny documentation site.
For further information on the services and API operations used by and surrounding this library, please see the following documentation: