Banyak pelanggan Looker ingin memberi pengguna mereka kemampuan yang lebih dari sekadar melaporkan data di data warehouse mereka, yaitu benar-benar menulis kembali dan memperbarui data warehouse tersebut.
Melalui Action API, Looker mendukung kasus penggunaan ini untuk data warehouse atau tujuan apa pun. Halaman dokumentasi ini memandu pelanggan yang menggunakan Google Cloud infrastruktur untuk men-deploy solusi di fungsi Cloud Run guna menulis kembali ke BigQuery. Halaman ini membahas beberapa topik berikut:
Pertimbangan solusi
Gunakan daftar pertimbangan ini untuk memvalidasi bahwa solusi ini sesuai dengan kebutuhan Anda.
- Cloud Run Functions
- Mengapa Cloud Run Functions? Sebagai penawaran "serverless" Google, fungsi Cloud Run adalah pilihan tepat untuk kemudahan operasi dan pemeliharaan. Satu pertimbangan yang perlu diingat adalah latensi, terutama untuk pemanggilan dingin, mungkin lebih lama daripada solusi yang mengandalkan server khusus.
- Bahasa dan Runtime Fungsi Cloud Run mendukung beberapa bahasa dan runtime. Halaman dokumentasi ini akan berfokus pada contoh di JavaScript dan Node.js. Namun, konsep ini dapat diterjemahkan secara langsung ke bahasa dan runtime lain yang didukung.
- BigQuery
- Mengapa BigQuery? Meskipun halaman dokumentasi ini mengasumsikan bahwa Anda sudah menggunakan BigQuery, BigQuery adalah pilihan tepat untuk data warehouse secara umum. Perhatikan pertimbangan berikut:
- BigQuery Storage Write API: BigQuery menawarkan beberapa antarmuka untuk memperbarui data di data warehouse Anda, termasuk, misalnya, pernyataan Bahasa Manipulasi Data (DML) dalam tugas berbasis SQL. Namun, opsi terbaik untuk operasi tulis bervolume tinggi adalah Storage Write API BigQuery.
- Menambahkan, bukan memperbarui: Meskipun solusi ini hanya akan menambahkan baris, bukan memperbarui baris, Anda selalu dapat memperoleh tabel "status saat ini" pada waktu kueri dari log khusus tambahan, sehingga menyimulasikan pembaruan.
- Mengapa BigQuery? Meskipun halaman dokumentasi ini mengasumsikan bahwa Anda sudah menggunakan BigQuery, BigQuery adalah pilihan tepat untuk data warehouse secara umum. Perhatikan pertimbangan berikut:
- Layanan pendukung
- Secret Manager: Secret Manager menyimpan nilai secret untuk memastikan nilai tersebut tidak disimpan di tempat yang terlalu mudah diakses, seperti langsung di konfigurasi fungsi.
- Identity and Access Management (IAM): IAM memberikan otorisasi pada fungsi untuk mengakses secret yang diperlukan saat runtime dan menulis ke tabel BigQuery yang diinginkan.
- Cloud Build: Meskipun Cloud Build tidak akan dibahas secara mendalam di halaman ini, fungsi Cloud Run menggunakannya di latar belakang, dan Anda dapat menggunakan Cloud Build untuk mengotomatiskan update yang terus di-deploy ke fungsi dari perubahan pada kode sumber di repositori Git.
- Tindakan dan autentikasi pengguna
- Akun Layanan Cloud Run Cara utama dan termudah untuk menggunakan tindakan Looker untuk integrasi dengan aset dan resource pihak pertama organisasi Anda sendiri adalah dengan mengautentikasi permintaan sebagai berasal dari instance Looker Anda menggunakan mekanisme autentikasi berbasis token Looker Action API, lalu memberikan otorisasi pada fungsi untuk memperbarui data di BigQuery menggunakan Akun Layanan.
- OAuth: Opsi lain, yang tidak dibahas di halaman ini, adalah menggunakan fitur OAuth Looker Action API. Pendekatan ini lebih kompleks dan umumnya tidak diperlukan, tetapi dapat digunakan jika Anda perlu menentukan akses pengguna akhir untuk menulis ke tabel menggunakan IAM, bukan menggunakan akses mereka di Looker atau logika ad hoc dalam kode fungsi Anda.
Panduan kode demo
Kami memiliki satu file yang berisi keseluruhan logika tindakan demo yang tersedia di GitHub. Di bagian ini, kita akan membahas elemen utama kode.
Kode penyiapan
Bagian pertama memiliki beberapa konstanta demo yang mengidentifikasi tabel yang akan ditulis oleh tindakan. Di bagian Panduan deployment nanti di halaman ini, Anda akan diminta untuk mengganti project ID dengan project ID Anda sendiri, yang akan menjadi satu-satunya modifikasi yang diperlukan pada kode.
/*** Demo constants */
const projectId = "your-project-id"
const datasetId = "demo_dataset"
const tableId = "demo_table"
Bagian berikutnya mendeklarasikan dan menginisialisasi beberapa dependensi kode yang akan digunakan tindakan Anda. Kami memberikan contoh yang mengakses Secret Manager "dalam kode" menggunakan modul Node.js Secret Manager; namun, Anda juga dapat menghilangkan dependensi kode ini dengan menggunakan fitur bawaan fungsi Cloud Run untuk mengambil secret untuk Anda selama inisialisasi.
/*** Code Dependencies ***/
const crypto = require("crypto")
const {SecretManagerServiceClient} = require('@google-cloud/secret-manager')
const secrets = new SecretManagerServiceClient()
const BigqueryStorage = require('@google-cloud/bigquery-storage')
const BQSManagedWriter = BigqueryStorage.managedwriter
Perhatikan bahwa dependensi @google-cloud
yang dirujuk juga dideklarasikan dalam file package.json
untuk memungkinkan dependensi dimuat sebelumnya dan tersedia untuk runtime Node.js. crypto
adalah modul Node.js bawaan dan tidak dideklarasikan di package.json
.
Penanganan dan pemilihan rute permintaan HTTP
Antarmuka utama yang diekspos kode Anda ke runtime fungsi Cloud Run adalah fungsi JavaScript yang diekspor yang mengikuti konvensi server web Node.js Express. Secara khusus, fungsi Anda menerima dua argumen: yang pertama mewakili permintaan HTTP, tempat Anda dapat membaca berbagai parameter dan nilai permintaan; dan yang kedua mewakili objek respons, tempat Anda mengeluarkan data respons. Meskipun nama fungsi dapat berupa apa pun yang Anda inginkan, Anda harus memberikan nama tersebut ke fungsi Cloud Run nanti, seperti yang dijelaskan di bagian Panduan deployment.
/*** Entry-point for requests ***/
exports.httpHandler = async function httpHandler(req,res) {
Bagian pertama fungsi httpHandler
mendeklarasikan berbagai rute yang akan dikenali oleh tindakan kita, yang mencerminkan endpoint yang diperlukan Action API untuk satu tindakan, dan fungsi yang akan menangani setiap rute, yang ditentukan nanti dalam file.
Meskipun beberapa tindakan + contoh fungsi Cloud Run men-deploy fungsi terpisah untuk setiap rute tersebut agar selaras satu per satu dengan pemilihan rute default fungsi Cloud Run, fungsi dapat menerapkan "sub-rute" tambahan dalam kodenya seperti yang ditunjukkan di sini. Hal ini pada akhirnya merupakan masalah preferensi, tetapi melakukan pemilihan rute tambahan ini dalam kode akan meminimalkan jumlah fungsi yang harus kita deploy dan membantu kita mempertahankan satu status kode yang koheren di semua endpoint tindakan.
const routes = {
"/": [hubListing],
"/status": [hubStatus], // Debugging endpoint. Not required.
"/action-0/form": [
requireInstanceAuth,
action0Form
],
"/action-0/execute": [
requireInstanceAuth,
processRequestBody,
action0Execute
]
}
Bagian lain dari fungsi pengendali HTTP menerapkan penanganan permintaan HTTP terhadap deklarasi rute sebelumnya dan menghubungkan nilai yang ditampilkan dari pengendali tersebut ke objek respons.
try {
const routeHandlerSequence = routes[req.path] || [routeNotFound]
for(let handler of routeHandlerSequence) {
let handlerResponse = await handler(req)
if (!handlerResponse) continue
return res
.status(handlerResponse.status || 200)
.json(handlerResponse.body || handlerResponse)
}
}
catch(err) {
console.error(err)
res.status(500).json("Unhandled error. See logs for details.")
}
}
Setelah pengendali HTTP dan deklarasi rute selesai, kita akan mempelajari tiga endpoint tindakan utama yang harus kita terapkan:
Endpoint Daftar Tindakan
Saat administrator Looker pertama kali menghubungkan instance Looker ke server Action, Looker akan memanggil URL yang disediakan, yang disebut sebagai "endpoint Daftar Tindakan", untuk mendapatkan informasi tentang tindakan yang tersedia melalui server.
Dalam deklarasi rute yang kami tampilkan sebelumnya, kami menyediakan endpoint ini di jalur root (/
) di URL fungsi, dan menunjukkan bahwa endpoint ini akan ditangani oleh fungsi hubListing
.
Seperti yang dapat Anda lihat dari definisi fungsi berikut, tidak ada terlalu banyak "kode" di dalamnya - fungsi ini hanya menampilkan data JSON yang sama setiap saat. Satu hal yang perlu diperhatikan adalah fungsi ini secara dinamis menyertakan URL "sendiri" ke dalam beberapa kolom, sehingga instance Looker dapat mengirim permintaan berikutnya kembali ke fungsi yang sama.
async function hubListing(req){
return {
integrations: [
{
name: "demo-bq-insert",
label: "Demo BigQuery Insert",
supported_action_types: ["cell", "query", "dashboard"],
form_url:`${process.env.CALLBACK_URL_PREFIX}/action-0/form`,
url: `${process.env.CALLBACK_URL_PREFIX}/action-0/execute`,
icon_data_uri: "data:image/png;base64,...",
supported_formats:["inline_json"],
supported_formattings:["unformatted"],
required_fields:[
// You can use this to make your action available
// for specific queries/fields
// {tag:"user_id"}
],
params: [
// You can use this to require parameters, either
// from the Action's administrative configuration,
// or from the invoking user's user attributes.
// A common use case might be to have the Looker
// instance pass along the user's identification to
// allow you to conditionally authorize the action:
{name: "email", label: "Email", user_attribute_name: "email", required: true}
]
}
]
}
}
Untuk tujuan demo, kode kami belum memerlukan autentikasi untuk mengambil listingan ini. Namun, jika Anda menganggap metadata tindakan Anda bersifat sensitif, Anda juga dapat mewajibkan autentikasi untuk rute ini, seperti yang ditunjukkan di bagian berikutnya.
Perhatikan juga bahwa fungsi Cloud Run dapat mengekspos dan menangani beberapa tindakan, yang menjelaskan konvensi rute /action-X/...
. Namun, fungsi Cloud Run demo kita hanya akan menerapkan satu tindakan.
Endpoint Formulir Tindakan
Meskipun tidak semua kasus penggunaan memerlukan formulir, memiliki formulir sangat cocok dengan kasus penggunaan penulisan ulang database, karena pengguna dapat memeriksa data di Looker, lalu memberikan nilai untuk dimasukkan ke dalam database. Karena Daftar Tindakan kami menyediakan parameter form_url
, Looker akan memanggil endpoint Formulir Tindakan ini saat pengguna mulai berinteraksi dengan tindakan Anda, untuk menentukan data tambahan yang akan diambil dari pengguna.
Dalam deklarasi rute, kita menyediakan endpoint ini di jalur /action-0/form
, dan mengaitkan dua pengendali dengannya: requireInstanceAuth
dan action0Form
.
Kita menyiapkan deklarasi rute untuk mengizinkan beberapa pengendali seperti ini karena beberapa logika dapat digunakan kembali untuk beberapa endpoint.
Misalnya, kita dapat melihat bahwa requireInstanceAuth
digunakan untuk beberapa rute. Kita menggunakan pengendali ini di mana pun kita ingin mewajibkan permintaan harus berasal dari instance Looker. Pengendali mengambil nilai token yang diharapkan dari Secret Manager dan menolak permintaan apa pun yang tidak memiliki nilai token yang diharapkan tersebut.
async function requireInstanceAuth(req) {
const lookerSecret = await getLookerSecret()
if(!lookerSecret){return}
const expectedAuthHeader = `Token token="${lookerSecret}"`
if(!timingSafeEqual(req.headers.authorization,expectedAuthHeader)){
return {
status:401,
body: {error: "Looker instance authentication is required"}
}
}
return
function timingSafeEqual(a, b) {
if(typeof a !== "string"){return}
if(typeof b !== "string"){return}
var aLen = Buffer.byteLength(a)
var bLen = Buffer.byteLength(b)
const bufA = Buffer.allocUnsafe(aLen)
bufA.write(a)
const bufB = Buffer.allocUnsafe(aLen) //Yes, aLen
bufB.write(b)
return crypto.timingSafeEqual(bufA, bufB) && aLen === bLen;
}
}
Perhatikan bahwa kita menggunakan implementasi timingSafeEqual
, bukan pemeriksaan kesetaraan standar (==
), untuk mencegah kebocoran informasi pengaturan waktu side-channel yang akan memungkinkan penyerang mengetahui nilai secret kita dengan cepat.
Dengan asumsi bahwa permintaan lulus pemeriksaan autentikasi instance, permintaan tersebut kemudian ditangani oleh pengendali action0Form
.
async function action0Form(req){
return [
{name: "choice", label: "Choose", type:"select", options:[
{name:"Yes", label:"Yes"},
{name:"No", label:"No"},
{name:"Maybe", label:"Maybe"}
]},
{name: "note", label: "Note", type: "textarea"}
]
}
Meskipun contoh demo kami sangat statis, kode formulir dapat lebih interaktif untuk kasus penggunaan tertentu. Misalnya, bergantung pada pilihan pengguna di drop-down awal, kolom yang berbeda dapat ditampilkan.
Endpoint Eksekusi Tindakan
Endpoint Action Execute adalah tempat sebagian besar logika tindakan berada, dan tempat kita akan mempelajari logika khusus untuk kasus penggunaan penyisipan BigQuery.
Dalam deklarasi rute, kita menyediakan endpoint ini di jalur /action-0/execute
, dan mengaitkan tiga pengendali dengannya: requireInstanceAuth
, processRequestBody
, dan action0Execute
.
Kita telah membahas requireInstanceAuth
, dan pengendali processRequestBody
sebagian besar menyediakan pra-pemrosesan yang tidak menarik untuk membuat kolom tertentu yang tidak praktis dalam isi permintaan Looker menjadi format yang lebih praktis, tetapi Anda dapat melihatnya di file kode lengkap.
Fungsi action0Execute
dimulai dengan menunjukkan contoh ekstraksi informasi dari beberapa bagian permintaan tindakan yang dapat berguna. Dalam praktiknya, perhatikan bahwa elemen permintaan yang disebut kode kita sebagai formParams
dan actionParams
dapat berisi kolom yang berbeda, bergantung pada apa yang Anda deklarasikan di endpoint Listingan dan Formulir.
async function action0Execute (req){
try{
// Prepare some data that we will insert
const scheduledPlanId = req.body.scheduled_plan && req.body.scheduled_plan.scheduled_plan_id
const formParams = req.body.form_params || {}
const actionParams = req.body.data || {}
const queryData = req.body.attachment.data //If using a standard "push" action
/*In case any fields require datatype-specific preparation, check this example:
https://github.com/googleapis/nodejs-bigquery-storage/blob/main/samples/append_rows_proto2.js
*/
const newRow = {
invoked_at: new Date(),
invoked_by: actionParams.email,
scheduled_plan_id: scheduledPlanId || null,
query_result_size: queryData.length,
choice: formParams.choice,
note: formParams.note,
}
Kode tersebut kemudian akan ditransisikan ke beberapa kode BigQuery standar untuk benar-benar menyisipkan data. Perhatikan bahwa Storage Write API BigQuery menawarkan variasi lain yang lebih kompleks dan lebih cocok untuk koneksi streaming persisten atau penyisipan massal banyak kumpulan data; tetapi, untuk merespons interaksi pengguna individual dalam konteks fungsi Cloud Run, ini adalah variasi yang paling langsung.
await bigqueryConnectAndAppend(newRow)
...
async function bigqueryConnectAndAppend(row){
let writerClient
try{
const destinationTablePath = `projects/${projectId}/datasets/${datasetId}/tables/${tableId}`
const streamId = `${destinationTablePath}/streams/_default`
writerClient = new BQSManagedWriter.WriterClient({projectId})
const writeMetadata = await writerClient.getWriteStream({
streamId,
view: 'FULL',
})
const protoDescriptor = BigqueryStorage.adapt.convertStorageSchemaToProto2Descriptor(
writeMetadata.tableSchema,
'root'
)
const connection = await writerClient.createStreamConnection({
streamId,
destinationTablePath,
})
const writer = new BQSManagedWriter.JSONWriter({
streamId,
connection,
protoDescriptor,
})
let result
if(row){
// The API expects an array of rows, so wrap the single row in an array
const rowsToAppend = [row]
result = await writer.appendRows(rowsToAppend).getResult()
}
return {
streamId: connection.getStreamId(),
protoDescriptor,
result
}
}
catch (e) {throw e}
finally{
if(writerClient){writerClient.close()}
}
}
Kode demo juga menyertakan endpoint "status" untuk tujuan pemecahan masalah, tetapi endpoint ini tidak diperlukan untuk integrasi Action API.
Panduan deployment
Terakhir, kami akan memberikan panduan langkah demi langkah untuk men-deploy demo sendiri, yang mencakup prasyarat, deployment fungsi Cloud Run, konfigurasi BigQuery, dan konfigurasi Looker.
Prasyarat project dan layanan
Sebelum mulai mengonfigurasi detail apa pun, tinjau daftar ini untuk memahami layanan dan kebijakan yang diperlukan solusi:
- Project baru: Anda memerlukan project baru untuk menyimpan resource dari contoh kami.
- Layanan: Saat pertama kali menggunakan fungsi BigQuery dan Cloud Run di UI konsol Cloud, Anda akan diminta untuk mengaktifkan API yang diperlukan untuk layanan yang diperlukan, termasuk BigQuery, Artifact Registry, Cloud Build, Cloud Functions, Cloud Logging, Pub/Sub, Cloud Run Admin, dan Secret Manager.
- Kebijakan untuk pemanggilan yang tidak diautentikasi: Kasus penggunaan ini mengharuskan kita men-deploy fungsi Cloud Run yang "mengizinkan pemanggilan yang tidak diautentikasi", karena kita akan menangani autentikasi untuk permintaan masuk dalam kode kita sesuai dengan Action API, bukan menggunakan IAM. Meskipun diizinkan secara default, kebijakan organisasi sering kali membatasi penggunaan ini. Secara khusus, kebijakan
constraints/iam.allowedPolicyMemberDomains
membatasi siapa yang dapat diberi izin IAM, dan Anda mungkin perlu menyesuaikannya untuk mengizinkan akun utamaallUsers
untuk akses yang tidak diautentikasi. Lihat panduan ini, Cara membuat layanan Cloud Run publik saat Berbagi yang Dibatasi Domain diterapkan untuk mengetahui informasi selengkapnya jika Anda tidak dapat mengizinkan pemanggilan yang tidak diautentikasi. - Kebijakan lainnya: Perhatikan bahwa Google Cloud batasan kebijakan organisasi lainnya juga dapat mencegah deployment layanan yang diizinkan secara default.
Men-deploy fungsi Cloud Run
Setelah membuat project baru, ikuti langkah-langkah berikut untuk men-deploy fungsi Cloud Run
- Di Cloud Run functions, klik Create Function.
- Pilih nama untuk fungsi Anda (misalnya, "demo-bq-insert-action").
- Di bagian setelan Pemicu:
- Jenis pemicu seharusnya sudah "HTTPS".
- Tetapkan Authentication ke Allow unauthenticated invocations.
- Salin nilai URL ke papan klip Anda.
- Di bagian setelan Runtime > Runtime environment variables:
- Klik Tambahkan variabel.
- Tetapkan nama variabel ke
CALLBACK_URL_PREFIX
. - Tempel URL dari langkah sebelumnya sebagai nilai.
- Klik Berikutnya.
- Klik file
package.json
, lalu tempelkan konten. - Klik file
index.js
, lalu tempelkan konten. - Tetapkan variabel
projectId
di bagian atas file ke project ID Anda sendiri. - Tetapkan Titik Entri ke
httpHandler
. - Klik Deploy.
- Berikan izin yang diminta (jika ada) ke Akun Layanan build.
- Tunggu hingga deployment selesai.
- Jika, pada langkah berikutnya, Anda mendapatkan error yang mengarahkan Anda untuk meninjau log Google Cloud , perhatikan bahwa Anda dapat mengakses log untuk fungsi ini dari tab Logs di halaman ini.
- Sebelum keluar dari halaman fungsi Cloud Run, di tab Details, temukan dan catat Service Account yang dimiliki fungsi tersebut. Kita akan menggunakannya di langkah-langkah berikutnya untuk memastikan bahwa fungsi tersebut memiliki izin yang diperlukan.
- Uji deployment fungsi Anda langsung di browser dengan membuka URL. Anda akan melihat respons JSON yang berisi listingan integrasi Anda.
- Jika Anda mendapatkan error 403, upaya Anda untuk menetapkan Izinkan pemanggilan yang tidak diautentikasi mungkin telah gagal secara diam-diam karena kebijakan organisasi. Periksa apakah fungsi Anda mengizinkan pemanggilan yang tidak diautentikasi, tinjau setelan kebijakan organisasi Anda, dan coba perbarui setelan tersebut.
Akses ke tabel tujuan BigQuery
Dalam praktiknya, tabel tujuan yang akan disisipkan dapat berada di project Google Cloud yang berbeda; tetapi, untuk tujuan demonstrasi, kita akan membuat tabel tujuan baru di project yang sama. Dalam kedua kasus tersebut, Anda harus memastikan bahwa Akun Layanan fungsi Cloud Run memiliki izin untuk menulis ke tabel.
- Buka konsol BigQuery.
Buat tabel demo:
- Di panel Penjelajah, gunakan menu elipsis di samping project Anda, lalu pilih Buat set data.
- Beri set data Anda ID
demo_dataset
, lalu klik Create dataset. - Gunakan menu elipsis pada set data yang baru dibuat, lalu pilih Create table.
- Beri nama tabel Anda
demo_table
. Di bagian Schema, pilih Edit as text, gunakan skema berikut, lalu klik Create table.
[ {"name":"invoked_at","type":"TIMESTAMP"}, {"name":"invoked_by","type":"STRING"}, {"name":"scheduled_plan_id","type":"STRING"}, {"name":"query_result_size","type":"INTEGER"}, {"name":"choice","type":"STRING"}, {"name":"note","type":"STRING"} ]
Tetapkan izin:
- Di panel Penjelajah, klik set data Anda.
- Di halaman set data, klik Sharing > Permissions.
- Klik Add Principal.
- Tetapkan New Principal ke Akun Layanan untuk fungsi Anda, yang telah dicatat sebelumnya di halaman ini.
- Tetapkan peran BigQuery Data Editor.
- Klik Save.
Menghubungkan ke Looker
Setelah fungsi Anda di-deploy, kita akan menghubungkan Looker ke fungsi tersebut.
- Kami memerlukan secret bersama untuk tindakan Anda guna mengautentikasi bahwa permintaan berasal dari instance Looker Anda. Buat string acak yang panjang dan amankan. Kita akan menggunakannya di langkah berikutnya sebagai nilai rahasia Looker.
- Di Konsol Cloud, buka Secret Manager.
- Klik Buat Secret.
- Tetapkan Name ke
LOOKER_SECRET
. (Ini di-hardcode dalam kode untuk demo ini, tetapi Anda dapat memilih nama apa pun secara efektif saat menggunakan kode Anda sendiri.) - Tetapkan Nilai Secret ke nilai secret yang Anda buat.
- Klik Buat Secret.
- Di halaman Secret, klik tab Permissions.
- Klik Grant Access.
- Tetapkan New Principals ke Akun Layanan untuk fungsi Anda, yang telah dicatat sebelumnya.
- Tetapkan peran Secret Manager Secret Accessor.
- Klik Save.
- Anda dapat mengonfirmasi bahwa fungsi berhasil mengakses secret dengan membuka rute
/status
yang ditambahkan ke URL fungsi Anda.
- Di instance Looker Anda:
- Buka Admin > Platform > Action.
- Buka bagian bawah halaman untuk mengklik Tambahkan Action Hub.
- Berikan URL fungsi Anda (misalnya, https://your-region-your-project.cloudfunctions.net/demo-bq-insert-action), lalu konfirmasi dengan mengklik Add Action Hub.
- Sekarang Anda akan melihat entri Action Hub baru dengan satu tindakan bernama Demo BigQuery Insert.
- Pada entri Action Hub, klik Konfigurasikan Otorisasi.
- Masukkan Looker Secret yang Anda buat ke kolom Authorization Token, lalu klik Update Token.
- Pada tindakan Demo BigQuery Insert, klik Enable.
- Alihkan tombol Aktifkan ke aktif.
- Pengujian tindakan akan otomatis berjalan, yang mengonfirmasi bahwa fungsi Anda menerima permintaan Looker dan merespons endpoint formulir dengan benar.
- Klik Save.
Pengujian menyeluruh
Sekarang kita seharusnya dapat benar-benar menggunakan tindakan baru. Tindakan ini dikonfigurasi agar berfungsi dengan kueri apa pun, jadi pilih Jelajah apa pun (misalnya, Jelajah Aktivitas Sistem bawaan), tambahkan beberapa kolom ke kueri baru, jalankan, lalu pilih Kirim dari menu roda gigi. Anda akan melihat tindakan tersebut sebagai salah satu tujuan yang tersedia, dan Anda akan diminta untuk memasukkan beberapa input kolom:
Setelah menekan Kirim, Anda akan melihat baris baru disisipkan ke dalam tabel BigQuery (dan email akun pengguna Looker Anda akan diidentifikasi di kolom invoked_by
).