Skip to content

Instantly share code, notes, and snippets.

@John-Dennert
Created January 26, 2016 08:37
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 John-Dennert/140ffcaee81d0b422bca to your computer and use it in GitHub Desktop.
Save John-Dennert/140ffcaee81d0b422bca to your computer and use it in GitHub Desktop.
/*Overall comments
*Identation is your friend and can make your code much easier to read (when you come back to it later)
and easier to maintain (speaking from personal experience)
*Don't do too many things in one line of code (yes, I'm starting to sound like my Freshman Computer Science professor :) )
*
*/
// Based on the script found here
// https://village.ccbchurch.com/message_comment_list.php?message_id=2530&view_increment=1&search_term=groups
// API functions has changed since the original post
// link to API documentation, http://designccb.s3.amazonaws.com/helpdesk/files/official_docs/api.html
function convert_meetingdays_to_text(meetingday) {
meetingdays_text = ["n/a", "Varies", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
return meetingdays_text[meetingday];
}
// Get Sheet and CCB Data
function getgroups() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var username_password ="username:password";
var CCBLink = "https://subdomain.ccbchurch.com/api.php?";
var CCBapi = "srv=group_profiles"; //make sure API user has access to this service
//if you don't want to get all of the group participants
//including participants will make the report run slower
CCBapi += "&include_participants=false"
//depending on how many groups your church has you may also want to set 'page' and 'per_page'
var ReportTitle = "Group Report";
var creds = Utilities.base64Encode(username_password);
var HEADERS = {"Authorization":"Basic " + creds};
var parameters = {
headers:HEADERS,
method :'post'
};
var xmltext = UrlFetchApp.fetch(CCBLink+CCBapi, parameters).getContentText();
var xdata = XmlService.parse(xmltext);
var groups = xdata.getRootElement().getChild('response').getChild('groups').getChildren();
// Clear Sheet
sheet.getDataRange().breakApart();
sheet.clear();
var cell = sheet.getRange("a1");
var column_index = 0;
// Write Column Headers
cell.setValue(ReportTitle).setFontSize(18);
sheet.getRange("a1:b1").mergeAcross(); //merges cells A1 and B1
//show when report was run
var time_zone = "EST";
cell.offset(0,7).setValue("Run on: " + Utilities.formatDate(new Date(), time_zone, "MM-dd-yyyy' at 'hh:mm aa")).setFontStyle("italic").setHorizontalAlignment("right");
cell.offset(1,column_index).setValue("Coach").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Group Name").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Leader Name").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Area of Town").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Type").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Description").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Meet Day").setFontWeight("bold");
column_index++;
cell.offset(1,column_index).setValue("Meet Time").setFontWeight("bold");
column_index++;
// Write Report Body
// each row will be a different group
var starting_row = 3;
var row_index = starting_row; //1st group will be on row 3, 2nd group on row 4 and so on
var previous_meetingday = ""
for (var i in groups) {
//row is info returned by the API about a group
group = groups[i];
// Filter to Select Groups
if (group.getChild("inactive").getText() == "true") { //don't display inactive groups
//do nothing
} else if (group.getChild("group_type").getText().substring(0,11) == "Life Group") { //if group type is Life Group
column_index = 0;
if(group.getChild('coach')) {
cell.offset(row_index,column_index).setValue(group.getChild('coach').getChildText("full_name"));
}
column_index++;
cell.offset(row_index,column_index).setValue(group.getChild("name").getText());
column_index++;
if(group.getChild('main_leader').getChild("full_name")) {
cell.offset(row_index,column_index).setValue(group.getChild('main_leader').getChildText("full_name"));
}
column_index++;
cell.offset(row_index,column_index).setValue(group.getChildText("area"));
column_index++;
cell.offset(row_index,column_index).setValue(group.getChildText("group_type"));
column_index++;
cell.offset(row_index,column_index).setValue(group.getChildText("description"));
column_index++;
if(group.getChild("meeting_day")) { //numeric representation of meeting_day, will be converted to text later
cell.offset(row_index,column_index).setValue(group.getChild("meeting_day").getAttribute('id').getValue());
}
column_index++;
if(group.getChild("meeting_time")) {
cell.offset(row_index,column_index).setValue(group.getChildText("meeting_time"));
}
row_index++; //switch to the next row (i.e. group)
}
}
// Sort report
//select row 3, column 1 through the last row (row_index), column 8 and sort using column 7, then column 8, then column 2
//column 7 = meetday, column 8 = meettime, column 2 = group name
sheet.getRange(3, 1, row_index, 8).sort([7, 8, 2]);
//get days that groups meet
var meeting_days = sheet.getRange(starting_row, 7, row_index-starting_row).getValues(); //starting at row 3, column 7, select meeting_day for all groups
var previous_day = "";
var offset = 0; //how many extra rows have been inserted
//Group groups by day they meet and insert an extra row
for (var i=0; i < meeting_days.length; i++) {
//convert numeric representation of meeting day to text
meetingday_text = convert_meetingdays_to_text(meeting_days[i][0]);
sheet.getRange(starting_row + i + offset, 7).setValue(meetingday_text);
if (previous_day == "") { //first group
sheet.insertRowBefore(starting_row + i + offset) //insert a row before the current row
//merge first cell of inserted row with the next 7 cells in the same row
sheet.getRange(starting_row + i + offset, 1, 1, 8).mergeAcross().setValue(meetingday_text).setFontWeight("bold").setHorizontalAlignment("center").setBackground("#EEEEEE");
offset += 1;
} else if (previous_day != meeting_days[i][0]) { //the day the previous group meet is not the same as the day the current group meets
sheet.insertRowBefore(starting_row + i + offset) //insert a row before the current row
//merge first cell of inserted row with the next 7 cells in the same row
sheet.getRange(starting_row + i + offset, 1, 1, 8).mergeAcross().setValue(meetingday_text).setFontWeight("bold").setHorizontalAlignment("center").setBackground("#EEEEEE");
offset += 1;
}
previous_day = meeting_days[i][0];
}
sheet.setColumnWidth(6,225);
}
@jasontucker
Copy link

John Dennert,

Thanks for helping me out, there doesn't seem to be much in open code for things like this which was why I put this on GitHub instead of being locked up here where no one can find it.

I added this in:

CCBapi += "&page=1&per_page=5&include_participants=false"

so I could get something to show up in the sheet. We have A LOT of groups. Either way I'm getting this error:
The coordinates or dimensions of the range are invalid. (line 136, file "Code")
var meeting_days = sheet.getRange(starting_row, 7, row_index-starting_row).getValues(); //starting at row 3, column 7, select meeting_day for all groups

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment