🦉
Metabase、SpreadSheetを利用して、Facebookのショップカタログの連携を自動化する
背景
- Facebook/Instagram用のカタログを追加したい
- Facebook/Instagram用のカタログの同期方法は以下の通り
- Eコマースプラットフォームをリンクする
- または、以下のフォーマットで商品情報を連携、またはアップロードする
- CSV、TSVまたはXML (RSS/ATOM) 形式で指定
- スプレッドシートを指定
- Eコマースプラットフォームを利用してないため、スプレッドシート経由で連携し、自動化して運用負荷を下げたい
システム構成
-
DB -> Metabase -> SpreadSheet -> Facebook
-
サーバーレスで対応したい
-
MetabaseからSpreadSheetの連携を自動化したい
DB -> Metabase
-
Facebookの所定のFormatで出力する
- Metabaseの質問(SQL)を作成
Metabase -> SpreadSheet (Metabase API)
- Metabase APIを使用する。curlで動作確認をしてみる
- Session Idを取得(14日できれる)
curl -X POST \
-H "Content-Type: application/json" \
-d '{"username": "user@example.com", "password": "pass"}' \
https://metabase.example.com/api/session
- Session Idから、カタログを取得
curl -X POST \
-H "Content-Type: application/json" \
-H "X-Metabase-Session: {Session-Id}" \
https://metabase.example.com/api/card/22/query/csv
Metabase -> SpreadSheet (GAS)
- Metabase APIをGoogle Apps Script(GAS)から呼ぶ
- Session-Idを取得してtableシートに保存
function importMetabaseSessionId() {
// Load Session-Id
var headers = {
'Content-Type': "application/json"
};
var options = {
"method" : "post",
"headers" : headers,
"payload" : "{\"username\": \"user@example.com\", \"password\": \"pass\"}",
"muteHttpExceptions": true
};
const url = "https://metabase.example.com/api/session";
var jsonContent = UrlFetchApp.fetch(url, options).getContentText();
var jsonData = Utilities.jsonParse(jsonContent);
var id = jsonData["id"]
// Save Session-Id
const sheetName = "table"
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1).setValue(id);
}
- catalogシートをクリア
function clearAllCells() {
const sheetName = "catalog"
var sheet = SpreadsheetApp.getActive().getSheetByName(sheetName);
sheet.getRange('A:L').clearContent();
}
- カタログを取得して保存
function importFacebookCatalogFromMetabase() {
// Load Saved Session-Id
const idSheetName = "table";
var tableSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(idSheetName);
var id = tableSheet.getRange(1, 1).getValue();
// Load CSV from Metabase
var headers = {
'Content-Type': "application/json",
'X-Metabase-Session': id
};
var options = {
"method" : "post",
"headers" : headers,
"muteHttpExceptions": true
};
const csvUrl = "https://metabase.example.com/api/card/22/query/csv";
var csvContent = UrlFetchApp.fetch(csvUrl, options).getContentText();
var csvData = Utilities.parseCsv(csvContent);
// Write CSV to sheet
const sheetName = "catalog";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
sheet.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
}
Metabase -> SpreadSheet (Securityの考慮)
- 問題点
- FacebookからFetchするために、ワークブックのURLを知ってれば誰でも閲覧可にする必要がある
- 方針
- 2つのワークブックを作成、データをコピーする
- GASでデータ取得用ワークブック(限定公開、コピー禁止)
- Facebook連携用ワークブック(誰でも閲覧可)
- 2つのワークブックを作成、データをコピーする
function copyCatalogToWorkBookForSync() {
const sheetName = "catalog";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName)
const outputWorkBookId = "{WorkBook-Id}"
var outputWorkBook = SpreadsheetApp.openById(outputWorkBookId)
// Delete same name sheet
var deleteSheet = outputWorkBook.getSheetByName(sheetName)
if (deleteSheet) {
outputWorkBook.deleteSheet(deleteSheet)
}
// Copy sheet for syncing to Facebook
var copiedSheet = sheet.copyTo(outputWorkBook)
copiedSheet.setName(sheetName)
// Move copied sheet to first position
outputWorkBook.setActiveSheet(copiedSheet)
outputWorkBook.moveActiveSheet(1)
}
GASを定期実行する
-
SessionIdの取得
-
カタログ取得、12時間毎
Facebook側の設定
- Fetch連携、12時間毎
まとめ
- FacebookのShop Catalogの連携をMetabaseとSpreadSheet、GASを使って自動化した
Discussion