-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
429 additions
and
417 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,68 +1,67 @@ | ||
// This function gets the start time of an event, based on the event's location time zone. | ||
const getStartTime = (event) => { | ||
const start_date = new Date(event.start_date); | ||
const output_date = new Date(start_date.toUTCString() + ' ' + dstOffset(start_date)); | ||
return output_date; | ||
const start_date = new Date(event.start_date); | ||
return new Date(start_date.toUTCString() + ' ' + dstOffset(start_date)); | ||
}; | ||
|
||
// This function gets the end time of an event, based on the event's location time zone. | ||
const getEndTime = (event) => { | ||
const start_date = getStartTime(event); | ||
const end_date = new Date(event.end_date); | ||
let output_date = new Date(end_date.toUTCString() + ' ' + dstOffset(end_date)) | ||
if (isNaN(output_date.getUTCFullYear())) { | ||
output_date = new Date(start_date.getTime() + (60 * 1000 * default_length_mins)) | ||
} | ||
return output_date; | ||
const start_date = getStartTime(event); | ||
const end_date = new Date(event.end_date); | ||
let output_date = new Date(end_date.toUTCString() + ' ' + dstOffset(end_date)) | ||
if (isNaN(output_date.getUTCFullYear())) { | ||
output_date = new Date(start_date.getTime() + (60 * 1000 * default_length_mins)) | ||
} | ||
return output_date; | ||
}; | ||
|
||
// This function returns the requested event ID if it is found in the Action Network event data. | ||
const getEventIDFromAN = (contentJSON, search_id) => { | ||
const identifiers = contentJSON.identifiers; | ||
const search_id_full = `${search_id}:[^,]*`; | ||
const identifiers = contentJSON.identifiers; | ||
const search_id_full = `${search_id}:[^,]*`; | ||
|
||
const regex_id = new RegExp(search_id_full) | ||
.exec(identifiers); | ||
if (regex_id === null) { | ||
Logger.log(`${search_id} not found in Action Network event identifiers.`); | ||
return null; | ||
} | ||
const regex_id = new RegExp(search_id_full) | ||
.exec(identifiers); | ||
if (regex_id === null) { | ||
Logger.log(`${search_id} not found in Action Network event identifiers.`); | ||
return null; | ||
} | ||
|
||
const found_id = regex_id[0].substring(search_id_full.indexOf('[')); | ||
Logger.log(`${search_id} found in Action Network event identifiers: ${found_id}`); | ||
const found_id = regex_id[0].substring(search_id_full.indexOf('[')); | ||
Logger.log(`${search_id} found in Action Network event identifiers: ${found_id}`); | ||
|
||
return found_id; | ||
return found_id; | ||
}; | ||
|
||
// This function returns all event data for an event ID from Action Network. | ||
const getAllANEventData = (event_url) => { | ||
return JSON.parse(UrlFetchApp.fetch(event_url, standard_api_params)) | ||
const getAllANEventData = (event_url, api_key) => { | ||
return JSON.parse(UrlFetchApp.fetch(event_url, standard_api_params(api_key))) | ||
}; | ||
|
||
// This function tags an Action Network event with the Google ID for its corresponding Google Calendar event | ||
const tagANEvent = async (action_network_id, google_id) => { | ||
// Check if the "AN_API_KEY" property is null | ||
if (scriptProperties.getProperty("AN_API_KEY") === null) { | ||
Logger.log('No Action Network API Key "AN_API_KEY" provided, cannot continue.'); | ||
return; | ||
} | ||
const tagANEvent = (action_network_id, google_id, api_key) => { | ||
// Check if the "AN_API_KEY" property is null | ||
if (api_key === null) { | ||
Logger.log('No Action Network API Key "AN_API_KEY" provided, cannot continue.'); | ||
return; | ||
} | ||
|
||
Logger.log(`Tagging Action Network event ${action_network_id} with Google Calendar event ID ${google_id}`); | ||
Logger.log(`Tagging Action Network event ${action_network_id} with Google Calendar event ID ${google_id}`); | ||
|
||
// Create a payload for the PUT request to Action Network, adding the Google ID as an identifier on the event | ||
const payload = JSON.stringify({ | ||
"identifiers": [`google_id:${google_id}`] | ||
}); | ||
// Create a payload for the PUT request to Action Network, adding the Google ID as an identifier on the event | ||
const payload = JSON.stringify({ | ||
"identifiers": [`google_id:${google_id}`] | ||
}); | ||
|
||
// Set the options for the request and send it to Action Network, logging the response | ||
const options = { | ||
method: "put", | ||
payload: payload, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'OSDI-API-Token': scriptProperties.getProperty("AN_API_KEY") | ||
} | ||
}; | ||
// Set the options for the request and send it to Action Network, logging the response | ||
const options = { | ||
method: "put", | ||
payload: payload, | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'OSDI-API-Token': api_key | ||
} | ||
}; | ||
|
||
UrlFetchApp.fetch(apiUrlAn + `events/${action_network_id}`, options); | ||
UrlFetchApp.fetch(apiUrlAn + `events/${action_network_id}`, options); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,50 @@ | ||
// This function returns event IDs from Action Network. If a filter is provided, it appends it to the API URL. | ||
const getANEventIDs = (filter) => { | ||
let url = `${apiUrlAn}events/`; | ||
if (filter != null) { | ||
Logger.log(`Finding upcoming events via filter query ${filter}.`); | ||
url += filter; | ||
} | ||
const content = UrlFetchApp.fetch(url, standard_api_params); | ||
return JSON.parse(content)["_links"]["osdi:events"]; | ||
const getANEventIDs = (filter, api_key) => { | ||
let url = `${apiUrlAn}events/`; | ||
if (filter != null) { | ||
Logger.log(`Finding upcoming events via filter query ${filter}.`); | ||
url += filter; | ||
} | ||
const content = UrlFetchApp.fetch(url, standard_api_params(api_key)); | ||
return JSON.parse(content)["_links"]["osdi:events"]; | ||
}; | ||
|
||
// This function sorts event IDs by date, based on the start time of the event. | ||
// It is used by the getSortedANEventIDs function to sort the event IDs by the soonest event first. | ||
const sortByDate = (a, b) => { | ||
const startTimeA = getStartTime(getAllANEventData(a.href)); | ||
const startTimeB = getStartTime(getAllANEventData(b.href)); | ||
return startTimeA - startTimeB; | ||
const startTimeA = getStartTime(a); | ||
const startTimeB = getStartTime(b); | ||
return startTimeA - startTimeB; | ||
} | ||
|
||
// This function returns upcoming event IDs from Action Network, sorted by the soonest event first. | ||
// If a filter is provided, it appends it to the API URL. | ||
const getSortedUpcomingANEventIDs = (extrafilters) => { | ||
let filter = `?filter=start_date gt '${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")}'`; | ||
if (extrafilters != null) { | ||
for (let i = 0; i < extrafilters.length; i++) { | ||
if (extrafilters[i] != null) { | ||
filter += extrafilters[i]; | ||
} | ||
const getSortedUpcomingANEventIDs = (extrafilters, api_key) => { | ||
let filter = `?filter=start_date gt '${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")}'`; | ||
|
||
if (extrafilters) { | ||
extrafilters.forEach(extrafilter => { | ||
if (extrafilter) { | ||
filter += extrafilter; | ||
} | ||
}); | ||
} | ||
} | ||
|
||
const eventsByCreation = getANEventIDs(filter) | ||
Logger.log("Sorting " + eventsByCreation.length + " Events By Soonest") | ||
const eventsByCreation = getANEventIDs(filter, api_key).map(event => getAllANEventData(event.href, api_key)); | ||
console.log("Sorting " + eventsByCreation.length + " Events By Soonest"); | ||
|
||
return eventsByCreation.sort(sortByDate) | ||
return eventsByCreation.sort(sortByDate); | ||
}; | ||
|
||
// This function returns event IDs from Action Network for events modified since a certain number of days ago that have not started yet. | ||
// It calculates the date to filter events by based on the current date and the number of days ago. | ||
const getRecentlyModifiedEventIDs = (daysago) => { | ||
const MILLIS_PER_DAY = 1000 * 60 * 60 * 24; | ||
const now = new Date(); | ||
const lastWeek = new Date(now.getTime() - (MILLIS_PER_DAY * daysago)); | ||
const filter_date = Utilities.formatDate(lastWeek, "UTC", "yyyy-MM-dd"); | ||
return getANEventIDs( | ||
`?filter=modified_date gt '${filter_date}' and start_date gt '${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")}'` | ||
); | ||
const getRecentlyModifiedEventIDs = (daysago, api_key) => { | ||
const MILLIS_PER_DAY = 1000 * 60 * 60 * 24; | ||
const now = new Date(); | ||
const lastWeek = new Date(now.getTime() - (MILLIS_PER_DAY * daysago)); | ||
const filter_date = Utilities.formatDate(lastWeek, "UTC", "yyyy-MM-dd"); | ||
return getANEventIDs( | ||
`?filter=modified_date gt '${filter_date}' and start_date gt '${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")}'`, | ||
api_key | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,63 +1,62 @@ | ||
// Creates a new Action Network Email Message with the provided HTML-formatted text as the body. | ||
// Values for Subject, Sender, Reply-To, Origin System, and Wrapper are obtained via defined Script Properties. | ||
const draftANMessage = (doc) => { | ||
const apiKey = scriptProperties.getProperty("AN_API_KEY"); | ||
const emailReplyTo = scriptProperties.getProperty("AN_EMAIL_REPLY_TO"); | ||
const emailSender = scriptProperties.getProperty("AN_EMAIL_SENDER"); | ||
const emailWrapper = scriptProperties.getProperty("AN_EMAIL_WRAPPER"); | ||
const emailCreator = scriptProperties.getProperty("AN_EMAIL_CREATOR"); | ||
const emailTarget = scriptProperties.getProperty("EMAIL_TARGET"); | ||
const emailSubject = scriptProperties.getProperty("EMAIL_SUBJECT"); | ||
|
||
if (!apiKey) { | ||
Logger.log('No Action Network Api Key "AN_API_KEY" provided, cannot continue.'); | ||
return; | ||
} | ||
if (!emailReplyTo) { | ||
Logger.log('No Email Reply-To Address "AN_EMAIL_REPLY_TO" provided, cannot continue.'); | ||
return; | ||
} | ||
if (!emailSubject) { | ||
Logger.log('No Email Subject "EMAIL_SUBJECT" provided, cannot continue.'); | ||
return; | ||
} | ||
|
||
const subject = `🌹 ${emailSubject} for ${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")} 🌹`; | ||
|
||
const payload = { | ||
subject, | ||
body: doc, | ||
from: emailSender, | ||
origin_system: "ActionNetworkEventSync", | ||
reply_to: emailReplyTo, | ||
_links: {} | ||
}; | ||
|
||
payload.targets = emailTarget ? [{ | ||
href: `${apiUrlAn}queries/${emailTarget}` | ||
}] : | ||
undefined; | ||
|
||
payload._links["osdi:wrapper"] = emailWrapper ? { | ||
href: `${apiUrlAn}wrappers/${emailWrapper}` | ||
} : | ||
undefined; | ||
|
||
payload._links["osdi:creator"] = emailCreator ? { | ||
href: `${apiUrlAn}people/${emailCreator}` | ||
} : | ||
undefined; | ||
|
||
const options = { | ||
method: "post", | ||
payload: JSON.stringify(payload), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'OSDI-API-Token': apiKey | ||
const draftANMessage = (doc, apiKey) => { | ||
const emailReplyTo = scriptProperties.getProperty("AN_EMAIL_REPLY_TO"); | ||
const emailSender = scriptProperties.getProperty("AN_EMAIL_SENDER"); | ||
const emailWrapper = scriptProperties.getProperty("AN_EMAIL_WRAPPER"); | ||
const emailCreator = scriptProperties.getProperty("AN_EMAIL_CREATOR"); | ||
const emailTarget = scriptProperties.getProperty("EMAIL_TARGET"); | ||
const emailSubject = scriptProperties.getProperty("EMAIL_SUBJECT"); | ||
|
||
if (!apiKey) { | ||
Logger.log('No Action Network Api Key "AN_API_KEY" provided, cannot continue.'); | ||
return; | ||
} | ||
if (!emailReplyTo) { | ||
Logger.log('No Email Reply-To Address "AN_EMAIL_REPLY_TO" provided, cannot continue.'); | ||
return; | ||
} | ||
if (!emailSubject) { | ||
Logger.log('No Email Subject "EMAIL_SUBJECT" provided, cannot continue.'); | ||
return; | ||
} | ||
}; | ||
|
||
const response = UrlFetchApp.fetch(`${apiUrlAn}messages/`, options); | ||
const actionNetworkId = getEventIDFromAN(JSON.parse(response), "action_network"); | ||
Logger.log(`Created Action Network Message ${actionNetworkId} with subject ${subject}.`); | ||
const subject = `🌹 ${emailSubject} for ${Utilities.formatDate(new Date(), "UTC", "yyyy-MM-dd")} 🌹`; | ||
|
||
const payload = { | ||
subject, | ||
body: doc, | ||
from: emailSender, | ||
origin_system: "ActionNetworkEventSync", | ||
reply_to: emailReplyTo, | ||
_links: {} | ||
}; | ||
|
||
payload.targets = emailTarget ? [{ | ||
href: `${apiUrlAn}queries/${emailTarget}` | ||
}] : | ||
undefined; | ||
|
||
payload._links["osdi:wrapper"] = emailWrapper ? { | ||
href: `${apiUrlAn}wrappers/${emailWrapper}` | ||
} : | ||
undefined; | ||
|
||
payload._links["osdi:creator"] = emailCreator ? { | ||
href: `${apiUrlAn}people/${emailCreator}` | ||
} : | ||
undefined; | ||
|
||
const options = { | ||
method: "post", | ||
payload: JSON.stringify(payload), | ||
headers: { | ||
'Content-Type': 'application/json', | ||
'OSDI-API-Token': apiKey | ||
} | ||
}; | ||
|
||
const response = UrlFetchApp.fetch(`${apiUrlAn}messages/`, options); | ||
const actionNetworkId = getEventIDFromAN(JSON.parse(response), "action_network"); | ||
Logger.log(`Created Action Network Message ${actionNetworkId} with subject ${subject}.`); | ||
}; |
Oops, something went wrong.