Skip to content

Instantly share code, notes, and snippets.

@theredpea
Last active November 9, 2022 04:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save theredpea/e21eb8147b8c5341d79b375e25117582 to your computer and use it in GitHub Desktop.
Save theredpea/e21eb8147b8c5341d79b375e25117582 to your computer and use it in GitHub Desktop.
// club.spond.com
///=============================
///=============================
///=============================
///=============================
const squid_spond_clubid = "39004B1375F244F4AFECC14513031501"
const fetch_opts = {
"credentials": "include",
"mode": "cors",
};
const spond_headers = {
"x-spond-clubid": squid_spond_clubid,
"x-spond-membershipauth": "undefined",
"content-type": "application/json",
// ...application_json
};
/*
let approved_members = [
{
"id": "26140AD3FA2C48228DD5E307603DA86E",
"PROFILE_BUT_FETCHING_LATER_BASED_ON_ID": {
"profileId": "F983E3C1AC4769506355010A6233FCAC",
"firstName": "SampleFirst",
"lastName": "SampleLast",
"email": "sample@email.com",
"phoneNumber": "+123456789",
"dateOfBirth": "2000-01-01",
"primaryContact": true
},
"firstName": "SampleFirst",
"lastName": "SampleLast"
}
]
*/
if (window.location.href.includes('club.spond.com')) {
const get_all_members_promise = () => {
return fetch("https://club.spond.com/club-api/v1/members?includeUnprocessed=true", {
"headers": { ...spond_headers },
...fetch_opts
}).then(_ => _.json());
}
const original_all_members_promise = get_all_members_promise();
/*
{
"id": "ADC946C5C6554DD08DDD8A89E6A59A4E",
"profile": {
"email": "...",
"phoneNumber": "...",
"primaryContact": true
},
"guardians": [],
"firstName": "...",
"lastName": "...",
"joinedDate": "yyyy-mm-dd",
"dateOfBirth": "yyyy-mm-dd",
"address": [
"...",
"...",
"...",
"..."
],
"country": "...",
"fieldValues": {},
"groups": [
{
"groupId": "1C7F6C0C4D594F30A4E7515FCC95B659",
"subGroups": [],
"respondent": true
}
],
"type": "E065C9BB4A136EC06BA017A16B30CBB4",
"gender": "..."
}
*/
// NOT NECESSARY
// const prop_map = {
// "id": "signupRequestId",
// "memberTypeId": "type",
// "member.firstName": "firstName",
// "member.lastName": "lastName",
// "nationality": "nationality",
// "": "ssn",
// "member.email": "profile.email",
// "member.phoneNumber": "profile.phoneNumber",
// "true": "profile.primaryContact",
// "adress": "address",
// "country": "country",
// "dateOfBirth": "dateOfBirth",
// // omit joinedDate, hopefully we dont change it (?) oh get it from the members endpoint , oh no, members dont include
// // "joinedDate"
// Oh no, use TODAY, or, timestamp
// https://spond.com/landing/groupInvite?groupCode=88114879A2068A8AB981CB824484D91D
const get_processing_requests_promise = () => {
return fetch("https://club.spond.com/club-api/v1/signupForm/requests?status=PROCESSING", {
"headers": { ...spond_headers },
...fetch_opts
}).then(_ => _.json());
}
const processing_requests_promise = get_processing_requests_promise();
/*
{
"id": "B8EFA452FBC14F04B2CFAB48DDEAA615",
"status": "PROCESSING",
"memberTypeId": "E065C9BB4A136EC06BA017A16B30CBB4",
"memberTypeName": "Member",
"groupId": "1C7F6C0C4D594F30A4E7515FCC95B659",
"groupName": "COMPETITIONS",
"forChild": false,
"member": {
"firstName": "...",
"lastName": "...",
"email": "...",
"phoneNumber": "+{0-9}"
},
"memberFieldValues": [],
"inputFieldValues": [
{
"id": "B6C4C53378D74F27BD4972641544257A",
"name": "Emergency Contact",
"value": "...",
"type": "LONG_TEXT"
}
],
"dateOfBirth": "...",
"gender": "...",
"address": [
"...",
"...",
"...",
"...",
],
"country": "...",
"nationality": "...",
"acceptedGuidelines": false,
"acceptedPhotography": false,
"timestamp": "2022-07-05T03:03:56.706Z"
}
*/
// };
let processing_aka_signup_requests = await processing_requests_promise;
console.error('SQUID SCRIPT: PROCESSING_AKA_SIGNUP_REQUESTS ', processing_aka_signup_requests);
let all_members = await original_all_members_promise;//();
console.error('SQUID SCRIPT: ALL_MEMBERS ', all_members);
// no the requests dont appear there yet
// processing_requests.map(request=>{
// const [member] = all_members.filter(member=>member.profile.email===request.member.email);
// return { signupRequestId:request.id, member};
// });
const approve_request_bodies = processing_aka_signup_requests.map(processing_request => {
return {
"signupRequestId": processing_request.id,
"type": processing_request.memberTypeId,
"firstName": processing_request.member.firstName,
"lastName": processing_request.member.lastName,
"nationality": processing_request.nationality,
"ssn": "",
"profile": {
"email": processing_request.member.email,
"phoneNumber": processing_request.member.phoneNumber,
"primaryContact": true,
},
"address": processing_request.address,
"country": processing_request.country,
"dateOfBirth": processing_request.dateOfBirth,
//
// "joinedDate": processing_request.timestamp.slice(0,10),
// use today:
"joinedDate": new Date().toISOString().slice(0, 10),
"gender": processing_request.gender,
"groups": [
{
"groupId": processing_request.groupId,
"subGroups": [],
"respondent": true
}
],
"guardians": [], //processing_request.guardians || [],
// try it (?)
"fieldValues": {}, //[], //processing_request.inputFieldValues Cannot deserialize instance of `java.util.LinkedHashMap<java.lang.String,java.lang.String>` out of START_ARRAY token
};
})
const get_approve_request_promise = (post_body) => {
// if (!signupRequestId) throw 'no signupRequestId';
// if (!member) throw 'no member';
// const post_body = {
// signupRequestId: signupRequestId,
// ...member
// };
// otherwise it looks like it sends back all members
delete post_body.id;
return fetch("https://club.spond.com/club-api/v1/members", {
"headers": spond_headers,
...fetch_opts,
"body": JSON.stringify(post_body),
"method": "POST",
// SAMPLE REQUEST BODY:
//"{\"signupRequestId\":\"B8EFA452FBC14F04B2CFAB48DDEAA615\",\"type\":\"E065C9BB4A136EC06BA017A16B30CBB4\",\"firstName\":\"...\",\"lastName\":\"...\",\"nationality\":\"...\",\"ssn\":\"\",\"profile\":{\"email\":\"...\",\"phoneNumber\":\"+...\",\"primaryContact\":true},\"address\":[\"...\",\"...\",\"...\",\"...\"],\"country\":\"...\",\"dateOfBirth\":\"...\",\"joinedDate\":\"2022-07-07\",\"gender\":\"...\",\"groups\":[{\"groupId\":\"1C7F6C0C4D594F30A4E7515FCC95B659\",\"subGroups\":[],\"respondent\":true}],\"guardians\":[],\"fieldValues\":{}}",
/*
{
"signupRequestId": "B8EFA452FBC14F04B2CFAB48DDEAA615",
"type": "E065C9BB4A136EC06BA017A16B30CBB4",
"firstName": "...",
"lastName": "...",
"nationality": "...",
"ssn": "",
"profile": {
"email": "...",
"phoneNumber": "+...",
"primaryContact": true
},
"address": [
"...",
"...",
"...",
"..."
],
"country": "...",
"dateOfBirth": "...",
"joinedDate": "2022-07-07",
"gender": "...",
"groups": [
{
"groupId": "1C7F6C0C4D594F30A4E7515FCC95B659",
"subGroups": [],
"respondent": true
}
],
"guardians": [],
"fieldValues": {}
}
*/
// SAMPLE RESPONSE:
/*
{"id":"7E1C340CCE7E4E7E8EDA70B3712C9682","profile":{"email":"...","phoneNumber":"+...","primaryContact":true},"guardians":[],"firstName":"Nate TEST","lastName":"Nate TEST","joinedDate":"2022-07-07","dateOfBirth":"1987-05-21","address":["1045 W Radcliff Ave TEST","Englewood TEST","80110","CO TEST"],"country":"...","fieldValues":{},"groups":[{"groupId":"1C7F6C0C4D594F30A4E7515FCC95B659","subGroups":[],"respondent":true}],"type":"E065C9BB4A136EC06BA017A16B30CBB4","gender":"..."}
{
"id": "7E1C340CCE7E4E7E8EDA70B3712C9682",
"profile": {
"email": "...",
"phoneNumber": "+...",
"primaryContact": true
},
"guardians": [],
"firstName": "Nate TEST",
"lastName": "Nate TEST",
"joinedDate": "2022-07-07",
"dateOfBirth": "1987-05-21",
"address": [
"1045 W Radcliff Ave TEST",
"Englewood TEST",
"80110",
"CO TEST"
],
"country": "...",
"fieldValues": {},
"groups": [
{
"groupId": "1C7F6C0C4D594F30A4E7515FCC95B659",
"subGroups": [],
"respondent": true
}
],
"type": "E065C9BB4A136EC06BA017A16B30CBB4",
"gender": "..."
}
*/
}).then(_ => _.json());
};
const approved_members = await Promise.all(approve_request_bodies.map(get_approve_request_promise));
/////
// the members who were all_members.filter(_=>_.joinedDate==='2022-07-07' && !_.deleted).map(_=>{return{id:_.id, profile: _.profile, firstName: _.firstName, lastName: _.lastName };})
console.error('SQUID SCRIPT: APPROVED_MEMBERS', approved_members);
const members_with_errors = approved_members.filter(member_response => (member_response.errorCode && member_response.error));
if (members_with_errors.length > 0) {
alert(`There was an error trying to approve ${members_with_errors.length} members; see console for message `)
console.error('SQUID SCRIPT: FAILED TO APPROVE_MEMBERS', members_with_errors);
}
const get_add_to_groups_promise = (member) => {
if (!member.id) { throw 'no member id! cannot add to group. Check Sign ups page, do you see "... sign-ups may be duplicates. Show duplicates only"' }
// The EVENTS AND SOCIALS GROUP:
// https://club.spond.com/club-api/v1/members/ADC946C5C6554DD08DDD8A89E6A59A4E/groups
const DENVER_SQUID_COMPETITIONS_GROUP = {
// ??? is this right ?
"groupId": "1C7F6C0C4D594F30A4E7515FCC95B659",
"subGroups": [],
"respondent": true,
"roles": []
};
// TODO USE real groups , fetch from:
// fetch("https://spond.com/api/2.1/groups/", {...
// });
// SAMPLE GROUPS RESPONSE
/*
[
{
"id": "1C7F6C0C4D594F30A4E7515FCC95B659",
"contactPerson": {
"contactMethod": "app",
"id": "AE3C958ED829B1AC925811D039CC3D5F",
"email": "...",
"firstName": "...",
"lastName": "...",
"imageUrl": "....jpeg",
"phoneNumber": "+...",
"unableToReach": false
},
"name": "COMPETITIONS",
"welcomeMessage": "In 2020, ... Squid re-branded to include the now over 150 members that participate in swimming, water polo, open water and triathlon training. ... Squid - Aquatics Club is ...'s largest LGBT & Allies aquatics club.",
"activity": "water_sports",
"clubId": "39004B1375F244F4AFECC14513031501",
"clubName": "... Squid - Aquatics Club",
"imageUrl": "https://spond.com/images/008/008a8b4f9e1f15a87b72c5c4acac4e64.jpeg",
"createdTime": "2021-02-26T17:50:42Z",
"members": [
{
"id": "006FE13CD22D480EBEF89C7F7BDC3354",
"profile": {
"contactMethod": "phone",
"id": "E509C6900ED77CB054EEB6EC6AE67025",
"firstName": "...",
"lastName": "...",
"phoneNumber": "+...",
"unableToReach": false
*/
const DENVER_SQUID_EVENTS_AND_SOCIALS_GROUP = {
"groupId": "22889135E02B47E3BC7BC38FBE2F3024",
"subGroups": [],
"respondent": true,
"roles": []
};
const DENVER_SQUID_PRACTICES_GROUP = {
"groupId": "5A1C0677D3C941C484FDB16C43AA80BA",
"subGroups": [
"4498F709819B45F29461271877229AD5",
"360ED40AB00A4A1B98DF7BE6DFC64AF0",
"95C722BDE6984ED0BC323CD1882B9FC6",
"98005CFF95EB438AB48241EAB5889BC4"
],
"respondent": true,
"roles": []
};
return Promise.all([
DENVER_SQUID_COMPETITIONS_GROUP,
DENVER_SQUID_EVENTS_AND_SOCIALS_GROUP,
DENVER_SQUID_PRACTICES_GROUP
].map(group_body => {
return fetch(`https://club.spond.com/club-api/v1/members/${member.id}/groups`, {
"headers": spond_headers,
...fetch_opts,
"body": JSON.stringify(group_body),
"method": "POST",
//
// SAMPLE EVENTS AND SOCIALS REQUEST:
// "body": "{\"groupId\":\"22889135E02B47E3BC7BC38FBE2F3024\",\"subGroups\":[],\"respondent\":true,\"roles\":[]}",
// SAMPLE EVENTS AND SOCIALS RESPONSE:
// {"id":"ADC946C5C6554DD08DDD8A89E6A59A4E","profile":{"email":"...","phoneNumber":"+...","primaryContact":true},"guardians":[],"firstName":"...","lastName":"...","joinedDate":"2022-07-07","dateOfBirth":"...","address":["...","...","...","..."],"country":"...","fieldValues":{},"groups":[{"groupId":"22889135E02B47E3BC7BC38FBE2F3024","subGroups":[],"respondent":true},{"groupId":"1C7F6C0C4D594F30A4E7515FCC95B659","subGroups":[],"respondent":true}],"type":"E065C9BB4A136EC06BA017A16B30CBB4","gender":"..."}
// SAMPLE PRACTICES REQUEST:
// {
// "groupId": "5A1C0677D3C941C484FDB16C43AA80BA",
// "subGroups": [
// "4498F709819B45F29461271877229AD5",
// "360ED40AB00A4A1B98DF7BE6DFC64AF0",
// "95C722BDE6984ED0BC323CD1882B9FC6",
// "98005CFF95EB438AB48241EAB5889BC4"
// ],
// "respondent": true,
// "roles": []
// }
// SAMPLE REQUEST IF ALREADY IN GROUP:
// may get a 400 response {"error":"Member is already in group"}
})
.then(_ => _.json());
}));
}
const added_to_groups_members = await Promise.all(approved_members.map(get_add_to_groups_promise));
// may get a 400 response {"error":"Member is already in group"}
console.error('SQUID SCRIPT: ADDED_TO_GROUPS_MEMBERS ', added_to_groups_members);
const all_members_after_approving = await get_all_members_promise();
const approved_members_with_member_info = all_members_after_approving.filter(member_with_profile => {
const is_approved = approved_members.some(approved_member => member_with_profile.id === approved_member.id);
const has_full_profile_with_profileId = (member_with_profile.profile || {}).profileId;
if (!has_full_profile_with_profileId) {
console.error('This member doesnt have a profileId, whats up ??? ', member_with_profile)
}
return is_approved; // && has_full_profile_with_profileId;
});
console.error('approved_members_with_member_info ', approved_members_with_member_info);
alert(`Now you must invite ${approved_members_with_member_info.length} members to events. FIRST copy(approved_members_with_member_info); , then switch over to new browser tab , log in to Spond client, as a user who can see all events (i.e. board member, member of all clubs)`);
copy(approved_members_with_member_info);
throw 'Cant go further here'
}
// if (!is_confirmed_can_see_all_events) {
// throw '!is_confirmed_can_see_all_events';
// }
// spond.com/client
///=============================
///=============================
///=============================
///=============================
if (window.location.href.includes('spond.com/client')) {
alert('Define const approved_members_with_member_info = ... first');
// const approved_members_with_member_info = ...
const upcoming_events = await fetch("https://spond.com/api/2.1/sponds/upcoming", {
...fetch_opts
}).then(_ => _.json());
const distinct_upcoming_series_events = (function () {
const upcoming_events_by_heading = {};
upcoming_events.forEach(upcoming_event => {
if (upcoming_events_by_heading[upcoming_event.heading]) {
return;
}
if (!upcoming_event.series) {
console.error('Not going to invite to this event because it is not a series event: ', upcoming_event);
return;
}
// get distinct events by their label
upcoming_events_by_heading[upcoming_event.heading] = upcoming_event;
});
return Object.values(upcoming_events_by_heading);
})();
const get_event_series_info_promise = (upcoming) => {
return fetch(`https://spond.com/api/2.1/sponds/${upcoming.id}?addProfileInfo=true&includeComments=true`, {
...fetch_opts
}).then(_ => _.json());
// Request URL: https://spond.com/api/2.1/sponds/4FACCDC360004563A2442D9C136DDC5A?addProfileInfo=true&includeComments=true
//
// SAMPLE RESPONSE, only 3 elements but response goes 163 long
// [
// {
// "id": "4FACCDC360004563A2442D9C136DDC5A",
// "updated": 1657203268499,
// "startTime": "2022-07-08T00:30:00Z",
// "heading": "THU: Polo Foundations|Practice [Carmody]",
// "unanswered": true,
// "series": true
// },
// {
// "id": "5C5E38FA597343CA9CC5AEB8ABE18DF0",
// "updated": 1657147917628,
// "startTime": "2022-07-08T00:30:00Z",
// "heading": "THU: Swim Practice [Carmody]",
// "unanswered": true,
// "series": true
// },
// {
// "id": "27610911BE95493FA9C6C23445B73D95",
// "updated": 1657151159831,
// "startTime": "2022-07-10T22:30:00Z",
// "heading": "SUN: Polo Scrimmage|Practice [Carmody]",
// "unanswered": true,
// "series": true
// }
// ....
// ]
}
const event_series_info = await Promise.all(distinct_upcoming_series_events.map(get_event_series_info_promise));
const get_add_member_to_event_promise = (members_with_profiles, event) => {
// const series_code = 'EED6297DED394A6ABCD3BDEC130923D2';
// const series_code = (function () { throw ' how to get series_code' })();
// const series_code = event.seriesId; //(function () { throw ' how to get series_code' })();
if (!event.seriesId) { throw '!event.seriesId' };
cosole.error(`Proccessing event ${event.seriesId}`)
const group_recipient_members = ((event.recipients || {}).group || {}).members;
if (!group_recipient_members) {
throw 'couldnt find group recipient members'
}
//
const group_members_who_need_processing = group_recipient_members.filter(_ => _.needsProcessing)
if (group_members_who_need_processing.length) {
alert(`There are ${group_members_who_need_processing.length} who need processing in this event`);
}
const group_member_ids = members_with_profiles.map(members_with_profile => {
const member_profile_id = (members_with_profile.profile || {}).profileId;
const member_email = (members_with_profile.profile || {}).email;
if (group_recipient_members.some(_ => !(_.profile))) {
// debugger;
console.error('SOME errors dont have profiles, reminder! DOES THIS MEAN they didnt accept aka unregistered aka more processing to do???? ', group_recipient_members.filter(_ => !(_.profile)))
}
const group_members = group_recipient_members.filter(_ => {
return ((member_profile_id && (_.profile || {}).id === member_profile_id)
|| (member_email && _.email === member_email));
})
const [group_member] = group_members;
if (group_members.length != 1) {
console.error(`Expected to find only one member that would match, but found ${group_members.length}; this might be an event the member *should not be invited to* (i.e. a board meeting)`);
debugger;
}
// debugger;
if (!group_member || !group_member.id) {
// debugger;
console.error(`Could not find group_member group_member.id for profile id ${member_profile_id}`)
return;
}
return group_member.id;
}).filter(_ => _);
// debugger;
// return;
if (group_member_ids.length === 0) {
throw `group_member_ids is empty; wouldnt work, would get 400 error`
}
// "body": "{\"fromOrdinal\":17,\"memberIds\":[\"95AA62FB24C243809CC371E4E8E57477\"]}",
// not just the member ID, but the members' ID within the specific group that is being invited (!)
// "heading": "THU: Polo Foundations|Practice [Carmody]",
// "description": "Time: 6:30PM-8:00PM MT*\nCost: $10 per practice (or) $60 per month\nLocation: 2200 S Kipling St, Lakewood, CO 80227\nEntrance Location: Please enter through the main gym entry\nOther: Please always wear your mask to the pool\n\n*If the practice time looks different then shown in practice description, your app may be set to a different time zone\n\nSee you there!",
// "startTimestamp": "2022-07-08T00:30:00Z",
// "endTimestamp": "2022-07-08T02:00:00Z",
// "location": {
// "id": "B274AF8F61A34D1FAD917A60A9257A11",
// "feature": "2200 S Kipling St",
// "address": "Lakewood",
// "latitude": 39.678116,
// "longitude": -105.108444
// },
// "recipients": {
// "group": {
// "id": "5A1C0677D3C941C484FDB16C43AA80BA",
// const member_ids = (function () { throw 'how to get member_ids ' })();
fetch(`https://spond.com/api/2.1/series/${event.seriesId}/respondents/add`, {
// SAMPLE REQUEST:
// "body": "{\"fromOrdinal\":17,\"memberIds\":[\"95AA62FB24C243809CC371E4E8E57477\"]}",
"body": JSON.stringify({
// like, from which event
fromOrdinal: event.seriesOrdinal,
memberIds: group_member_ids
}),
"headers": spond_headers,
// SAMPLE response: empty
"method": "POST",
...fetch_opts
// SAMPLE REQUEST:
// fetch("https://spond.com/api/2.1/series/EED6297DED394A6ABCD3BDEC130923D2/respondents/add", {
// 867F95AAD80A4B35BAD255FFDD531BD5 is ...
// 95AA62FB24C243809CC371E4E8E57477 is ...
// "body": "{\"fromOrdinal\":17,\"memberIds\":[\"867F95AAD80A4B35BAD255FFDD531BD5\",\"B5E617E2CDA5493DA26481A8358103FC\",\"95AA62FB24C243809CC371E4E8E57477\"]}",
// });
// this one failed
// BFAFCE68D44A4F8DAF0D0B6316E82F01
}).then(_ => _.json());
}
const adding_groups_to_event_series = await Promise.all(event_series_info.map(event_series => {
return get_add_member_to_event_promise(approved_members_with_member_info, event_series);
}))
var did_extra_steps = window.confirm('You should also visit each group, from spond.com/client, and approve the members, check group recipients and needsProcessing; may still see message "Not accepted group invite yetWhenever an event invite or post is sent to this person, the person will receive a reminder about the group invitation."');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment