See this example. It's a Google Doc with a script to create a sidebar with a table of contents.
Below is just the code to get the list of headers. The linked document has everything in its Script Editor.
//Recursively get subsections
function getHeadersFromParagraphs(paragraphs, limit, starter){
var headers = [], header, hType, level, start, result,
paragraph,
heading,
i,
h1 = DocumentApp.ParagraphHeading.HEADING1,
h2 = DocumentApp.ParagraphHeading.HEADING2,
h3 = DocumentApp.ParagraphHeading.HEADING3,
h4 = DocumentApp.ParagraphHeading.HEADING4,
h5 = DocumentApp.ParagraphHeading.HEADING5,
h6 = DocumentApp.ParagraphHeading.HEADING6,
hTypes = [h1,h2,h3,h4,h5,h6];
//Loop through all paragraphs
start = starter ? starter.id+1 : 0;
for(i = start; i < paragraphs.length; i += 1){
paragraph = paragraphs[i];
heading = paragraph.getHeading();
level = hTypes.indexOf(heading);
if(level > -1 && level < limit){
if(paragraph.getText() == "") continue;
if(starter && level <= starter.level) { i--; break; }
header = { name : paragraph.getText(), id : i, level : level };
result = getHeadersFromParagraphs(paragraphs, limit, header);
i = result.index;
header.subheaders = result.headers;
headers.push(header);
}
}
return { headers : headers, index : i }
}
//Initiate parsing of headers. By default, limit to Heading 1.
function pullHeaders(level){
level = level || 1;
var body = DocumentApp.getActiveDocument().getBody(),
paragraphs = body.getParagraphs();
var result = getHeadersFromParagraphs(paragraphs, level);
return JSON.stringify(result.headers);
}