Bloggerのサイトマップ(投稿一覧)を自動作成する
完成品
作成目的
ブログ全体に存在する記事/ページを簡易表示したい。ブログの全体を簡易に閲覧可能なページを作成したい。ただし、記事作成毎に更新するのは大変なため、自動更新としたい。
作成経緯
- Blogger 記事 を 一覧 表示 する ページ の 作成方法 - galifeで作成する
- 目的のものが作成出来るが、以下の点が不満
- JavaScriptの使用が必須
- 一覧表示までに遅延(数秒)が発生する
- 不満点解消のため、自作する
動作概要
- 投稿一覧をスプレットシートに記入する
- ページ一覧をスプレットシートに記入する
- 投稿一覧とページ一覧を使用してBloggerページを更新する
- 投稿一覧、ページ一覧からサイトマップページのHTMLを作成する
- OAuth2のアクセストークンを取得する
- BloggerAPIでページを更新する
- GoogleAppsScriptのトリガー設定でスクリプトを自動実行する
ソースコード
sitemap.gsvar blogid = '{BloggerID}';
var pageid = '{ページID}';
var sheetid = '{スプレッドシートID}';
// アクセストークンの取得
function fetchAccessToken() {
var client_id = '{クライアントID}';
var client_secret = '{クライアント シークレット}';
var redirect_uri = '{リダイレクトURI}';
var refresh_token = '{リフレッシュトークン}';
var res = UrlFetchApp.fetch("https://www.googleapis.com/oauth2/v4/token", {
"method" : "POST",
payload : {
"refresh_token" : refresh_token,
"client_id" : client_id,
"client_secret" : client_secret,
"redirect_uri" : redirect_uri,
"grant_type" : "refresh_token"
}
//, muteHttpExceptions : true
});
return JSON.parse(res.getContentText());
}
function createBlogContent(sheetApp, type) {
var isPost = (type == 'posts');
var sheet = sheetApp.getSheetByName(type);
var row = sheet.getLastRow();
if (row <= 1) {
return '';
}
// A1=(1, 1)
var values = sheet.getRange(2, 1, row-1, 4).getValues();
var list = [];
for (var i=0; i<values.length; i++) {
list.push({url:values[i][0],update:values[i][1],posted:values[i][2],title:values[i][3]});
}
// タイトルで並び替え
list.sort(function(a, b) {
var at = a.title.toUpperCase();
var bt = b.title.toUpperCase();
if (at < bt) { return -1; }
if (at > bt) { return 1; }
return 0;
});
// HTML作成
var lines = [];
var now = Date.now();
lines.push('<ul class="poststoc-list">');
list.forEach(function(v, i, a) {
var url = v.url;
if (url.indexOf('https:') == 0) { url = url.substr(6); }
if (url.indexOf('http:') == 0) { url = url.substr(5); }
var posted = new Date(v.posted).getTime();
lines.push('<li class="poststoc-item">');
lines.push('<span class="poststoc-title"><a href="'+url+'">'+v.title+'</a></span>');
// 28日以内
if (isPost && now < posted + 28*24*60*60*1000) {
lines.push('<span class="poststoc-new">NEW !</span>');
}
lines.push('</li>');
});
lines.push('</ul>');
return lines.join('');
}
function createLabelContent(sheetApp) {
var sheet = sheetApp.getSheetByName('posts');
var row = sheet.getLastRow();
if (row <= 1) {
return '';
}
// ラベル取得
var values = sheet.getRange(2, 5, row-1, 1).getValues();
var list = [];
for (var i=0; i<values.length; i++) {
var array = values[i][0].split(',');
for (var k=0; k<array.length; k++) {
if (list.indexOf(array[k]) == -1) {
list.push(array[k]);
}
}
}
list.sort(function(a, b) {
var at = a.toUpperCase();
var bt = b.toUpperCase();
if (at < bt) { return -1; }
if (at > bt) { return 1; }
return 0;
});
// HTML作成
var lines = [];
lines.push('<ul class="poststoc-list label">');
list.forEach(function(v, i, a) {
if (v != '') {
lines.push('<li class="poststoc-item">');
lines.push('<span class="poststoc-title"><a href="//www.bugbugnow.net/search/label/'+v+'">'+v+'('+obj[v]+')</a></span>');
lines.push('</li>');
}
});
lines.push('</ul>');
return lines.join('');
}
// コンテンツ作成
function createSitemapContent() {
// スプレットシートの取得
var sheetApp = SpreadsheetApp.openById(sheetid);
// HTML作成
var lines = [];
var now = Date.now();
lines.push('<style>.poststoc-new{margin-left:1em;font-size:small;color:#F08300;}.poststoc-list.label{list-style-type: none;}.poststoc-list.label li{display: inline-block;padding-right: 0.75em;}</style>');
lines.push('<div class="poststoc">');
/*
lines.push('<ul class="poststoc-list">');
lines.push('<li class="poststoc-item">');
lines.push('<span class="poststoc-title"><a href="//www.bugbugnow.net/">TOP</a></span>');
lines.push('</li>');
lines.push('</ul>');
*/
lines.push('<h4>投稿</h4>');
lines.push(createBlogContent(sheetApp, 'posts'));
lines.push('<h4>ページ</h4>');
lines.push(createBlogContent(sheetApp, 'pages'));
lines.push('<h4>ラベル</h4>');
lines.push(createLabelContent(sheetApp));
lines.push('</div>');
return lines.join('');
}
// サイトマップ更新
function updateSitemap() {
var credentials = fetchAccessToken();
//リクエストの設定
var json = {
title: 'サイトマップ',
content: createSitemapContent()
};
var fetchOptions = {
method:"PUT",
contentType:"application/json",
headers:{
Authorization:"Bearer "+credentials.access_token,
},
payload:JSON.stringify(json)
};
//リクエストURLを作成
var url = 'https://www.googleapis.com/blogger/v3/blogs/'+blogid+'/pages/'+pageid;
//fetch
var res = UrlFetchApp.fetch(url, fetchOptions);
// ログ
Logger.log(url);
Logger.log(res.getContentText());
}
function sitemap() {
// 投稿一覧更新
updatePost();
// ページ一覧更新
updatePage();
// サイトマップを更新する
updateSitemap();
}
更新履歴
更新日 | 内容 |
---|---|
2018/07/01 | 初版 |
2018/08/12 | [fix] ラベルなし対応 |
補足
上記ソースコードを使用する場合、下記の値を変更する必要があります。
- {BloggerID}
- 管理ページのURLから取得可能です
- {ページID}
- 管理ページのURLから取得可能です
- {スプレッドシートID}
- スプレットシートのURLから取得可能です
- {クライアントID}
- {クライアント シークレット}
- {リダイレクトURI}
- {リフレッシュトークン}
- GoogleAPIsから取得可能です
- BloggerのGoogleアカウントで取得する必要があります
- リフレッシュトークンは、別途認証を行い取得する必要があります
www.bugbugnow.net
- 使用するサイトのドメイン