Spreadsheet ( Google Sheets ), Google Apps Script, Blogger API を用いて Blogger へ投稿 / 削除 をする
スプレッドシートに入力した内容をもとに Google Blogger に投稿することができます。
Google Blogger は「作成ビュー」と「 HTML ビュー」が用意されていて、頑張れば複雑なデザインや機能をもった投稿をすることができますが、都度 html を記述するのは面倒ですよね。
特に、html テンプレートに沿ってコードに明るくない運用者が更新作業を行う場合は、表示崩れのリスクが大きくなります。そんなときに便利なのは、( Google Form 、)Google Sheet 、Blogger を連携した投稿です。
Google Sheet に入力したテキストや Google Drive に保存したあ画像の内容から html を作成し、GAS で Blogger API を利用して Blogger に投稿することができます。(ここでは、投稿されてある内容の更新、削除には触れません。)
では、始めましょう!
スプレッドシートの準備
スプレッドシートと連携して操作するときは大半は、どのシートのデータを取得するかという設定です。ベースとなるスプレッドシートを準備し、UI と Spreadsheet ID, Sheet Name まわりを確認します。
今回の全容
var ui = SpreadsheetApp.getUi(); var ss = SpreadsheetApp.getActive(); var clientId = ss.getRange("clientId").getValue(); var secretKey = ss.getRange("secretKey").getValue(); var blogId = ss.getRange("blogId").getValue(); var vehicleId = ss.getRange("vehicleId").getValue(); var content = ss.getRange("content").getValue(); var caption = ss.getRange("caption").getValue(); var title = ss.getRange("title").getValue(); var maker = ss.getRange("maker").getValue(); var imageFolder = ss.getRange("imageFolder").getValue(); var status = ss.getRange("status"); function onOpen(){ ui.createMenu("Blogger") .addItem("Sign in", "login") .addItem("New post", "newPost") .addItem("Log out", "logout") .addToUi(); } function getBloggerService(){ var service = OAuth2.createService("blogger") // Set the endpoint URLs, which are the same for all Google services. .setAuthorizationBaseUrl('https://accounts.google.com/o/oauth2/auth') .setTokenUrl('https://accounts.google.com/o/oauth2/token') // Set the client ID and secret, from the Google Developers Console. .setClientId(clientId) .setClientSecret(secretKey) // Set the name of the callback function in the script referenced // above that should be invoked to complete the OAuth flow. .setCallbackFunction('authCallback') // Set the property store where authorized tokens should be persisted. .setPropertyStore(PropertiesService.getUserProperties()) .setCache(CacheService.getUserCache()) // Set the scopes to request (space-separated for Google services). .setScope('https://www.googleapis.com/auth/blogger') // Below are Google-specific OAuth2 parameters. // Sets the login hint, which will prevent the account chooser screen // from being shown to users logged in with multiple accounts. .setParam('login_hint', Session.getActiveUser().getEmail()) // Requests offline access. .setParam('access_type', 'offline') // Forces the approval prompt every time. This is useful for testing, // but not desirable in a production application. .setParam('approval_prompt', 'force'); return service; } function login() { var blogger = getBloggerService(); if (!blogger.hasAccess()) { var authorizationUrl = blogger.getAuthorizationUrl(); var template = HtmlService.createTemplate( '<a href="<?= authorizationUrl ?>" target="_blank">Authorize</a>. ' + 'You can close this dialog once the authorization is done!'); template.authorizationUrl = authorizationUrl; var page = template.evaluate(); ui.showModalDialog(page, "Sign in with Google"); status.setValue("You are now logged in."); } else { // ... ui.alert("You've already signed in."); } } function logout(){ var service = getBloggerService(); service.reset(); ui.alert("You are now logged out."); status.setValue("You are now logged out."); } function authCallback(request) { var blogger = getBloggerService(); var isAuthorized = blogger.handleCallback(request); if (isAuthorized) { return HtmlService.createHtmlOutput('Success! You can close this tab.'); } else { return HtmlService.createHtmlOutput('Denied. You can close this tab'); } } function newPost() { var blogger = getBloggerService(); if (blogger.hasAccess()){ status.setValue("Starting to create new post...") .setFontColor("red"); SpreadsheetApp.flush(); var url = "https://www.googleapis.com/blogger/v3/blogs/"+ blogId +"/posts" var images = getImages(); var sliders = "</div><div class='modal mbr-slider' tabindex='-1' role='dialog' aria-hidden='true' id='spsqy4Dmw8-modal'>" + "<div class='modal-dialog' role='document'>" + "<div class='modal-content'><div class='modal-body'><div class='carousel slide' id='lb-spsqy4Dmw8' data-interval='5000'>" + "<div class='carousel-inner'>" + getSliders().slice(0,25) + " active" + getSliders().slice(25) + "</div><ol class='carousel-indicators'><li data-slide-to='0' class='active' data-target='#lb-spsqy4Dmw8'></li>" + "<li data-slide-to='1' data-target='#lb-spsqy4Dmw8'></li><li data-slide-to='2' data-target='#lb-spsqy4Dmw8'></li>" + "<li data-slide-to='3' data-target='#lb-spsqy4Dmw8'></li></ol><a role='button' href='' class='close' data-dismiss='modal' aria-label='Close'></a>" + "<a class='carousel-control-prev carousel-control' role='button' data-slide='prev' href='#lb-spsqy4Dmw8'>" + "<span class='mobi-mbri mobi-mbri-arrow-prev' aria-hidden='true'></span><span class='sr-only'>Previous</span></a>" + "<a class='carousel-control-next carousel-control' role='button' data-slide='next' href='#lb-spsqy4Dmw8'>" + "<span class='mobi-mbri mobi-mbri-arrow-next' aria-hidden='true'></span><span class='sr-only'>Next</span> </a> </div> </div> </div> </div> </div></div></section> " + "<section class='content15 cid-soh0Z3ZRTx' id='content15-2n'><div class='container'><div class='row justify-content-center'>" + "<div class='card col-md-12 col-lg-12'><div class='card-wrapper'> <div class='card-box align-left'> <h4 class='card-title mbr-fonts-style mbr-white mb-3 display-7'>" + "<strong>諸元</strong></h4> <p class='mbr-text mbr-fonts-style display-4'>"; var blogContent = content + images + sliders + caption; var productMaker = maker; // Logger.log(blogContent); var data = { "kind": "blogger#post", "blog": { "id": blogId }, "title": title, "content": blogContent, "labels": [ productMaker ] }; var options = { "method": "POST", "headers":{ "authorization": 'Bearer ' + blogger.getAccessToken() }, "contentType": "application/json", "payload": JSON.stringify(data) }; var post = UrlFetchApp.fetch(url, options).getContentText(); post = JSON.parse(post); status.setValue('=HYPERLINK("'+ post['url'] + '", "Visit the new post")') .setFontColor("green"); }else{ ui.alert("Please login!"); } } function getImages(){ var folder = DriveApp.getFolderById(imageFolder); var files = folder.getFiles(); var images = []; while(files.hasNext()){ var file = files.next(); var type = file.getMimeType(); if (type.indexOf("image") >= 0){ var id = file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW).getId(); var name = nameWoExt(file.getName()) var url = "https://drive.google.com/uc?export=download&id=" + id; images.push("<div class='col-12 col-md-6 col-lg-3 item gallery-image'>" + "<div class='item-wrapper' data-toggle='modal' data-target='#spsqy4Dmw8-modal'>" + "<img class='w-100' src='" + url + "' alt='' data-slide-to='0' data-target='#lb-spsqy4Dmw8'>" + "<div class='icon-wrapper'>" + "<span class='mobi-mbri mobi-mbri-search mbr-iconfont mbr-iconfont-btn'>" + "</span>"+"</div>"+"</div>"+"</div>"); } } return images.join(""); } function getSliders(){ var folder = DriveApp.getFolderById(imageFolder); var files = folder.getFiles(); var images = []; while(files.hasNext()){ var file = files.next(); var type = file.getMimeType(); if (type.indexOf("image") >= 0){ var id = file.setSharing(DriveApp.Access.ANYONE, DriveApp.Permission.VIEW).getId(); var name = nameWoExt(file.getName()) var url = "https://drive.google.com/uc?export=download&id=" + id; images.push("<div class='carousel-item'><img class='d-block w-100' src='" + url + "' alt='" + name + "'></div>"); } } return images.join(""); } function nameWoExt(name){ var i = name.lastIndexOf("."); return name.slice(0,i); }
コメント
コメントを投稿