
Kami memiliki dua formulir google, masing-masing 75 pertanyaan, 5 pengguna bisnis yang secara aktif mengedit formulir ini, dan juga skrip google yang mengekspor formulir ke JSON. Bukan berarti akan sulit untuk menjalankannya setiap kali dengan tangan Anda, tetapi begitu Anda mulai mengotomatisasi pekerjaan Anda, maka pergilah dalam hobi ini sampai akhir.
Dalam dokumentasi resmi, iblis akan mematahkan kakinya, jadi di bawah kucing kita akan melihat lebih dekat pada unduhan jarak jauh dan peluncuran Google Apps Script melalui REST API menggunakan Python.
Pendahuluan
Di Dokter Dekat, kami sedang mengembangkan platform untuk bot obrolan, di mana formulir Google digunakan untuk menggambarkan skenario. Oleh karena itu, saya ingin menerima dari formulir di klik tombol JSON yang berisi node (form points) dan metadata ke mereka (transisi antara node, jenis node, nama mereka). Tampaknya keinginannya sederhana, tetapi Google tidak mendukung fungsi ini dan Anda harus mengumpulkan "pengekspor" ini dengan tangan Anda sendiri. Pertimbangkan langkah-langkah untuk membuatnya.
LANGKAH 1. Skrip Google Apps
Google telah menyediakan kemampuan untuk berinteraksi dengan layanannya (Lembar, Dokumen, Formulir) melalui Google Apps Script - skrip yang ditulis dalam skrip google (.gs). Artikel ini tidak menyediakan penguraian bahasa skrip google, jadi saya akan memberikan contoh skrip siap pakai yang membuat JSON dari formulir Google yang ada.
Kode pengguna
Steven Schmatz diambil dari github sebagai dasar, yang untuknya saya mengucapkan terima kasih kepadanya.
Apa yang terjadi dalam kode:
- fungsi getFormMetadata - mengembalikan JSON dengan form metadata
- Fungsi itemToObject - mengubah objek form.item ke JSON dengan bidang yang diperlukan
- fungsi sendEmail - mengirim file JSON ke email yang ditentukan dalam teks
- fungsi utama - mengembalikan JSON yang dihasilkan
- variabel form_url di fungsi utama adalah alamat formulir google kami
LANGKAH 2. Menguji skrip
Saat ini, kinerja skrip dapat diperiksa sebagai berikut:
- buat proyek skrip aplikasi Anda sendiri
- salin kodenya ke dalamnya
- alih-alih <YOUR_FORM_URL> kami mengganti alamat formulir kami dari formulir docs.google.com/forms/d/FORM_IDENTIFICATOR/edit
- batalkan komentar pada panggilan untuk mengirimEmail dalam fungsi utama
- alih-alih <YOUR_EMAIL> kami mengganti alamat email yang ingin kami terima JSON
- selamatkan proyek
- jalankan fungsi utama
- jika ini adalah skrip pertama yang dijalankan, sistem akan memberi tahu Anda tentang perlunya memberikan skrip izin untuk mengirim email dari alamat Anda. Jangan takut. Ini adalah prosedur standar yang diperlukan untuk menguji skrip. Buka "Tinjau izin" -> pilih akun Anda -> "Tingkat Lanjut" -> "Masuk ke proyek PROJECT_NAME (tidak aman)" -> "Izinkan"
- menunggu skrip bekerja
- lihat di kotak surat dan lihat file JSON dalam bentuk teks
Semuanya akan baik-baik saja, tetapi penggunaan lebih lanjut dari data yang diperoleh melibatkan penyalinan manual dari surat, pemrosesan teks ini (dengan python, misalnya) dan menyimpan file yang dihasilkan. Kedengarannya tidak terlalu siap produksi. Kami mengotomatiskan peluncuran skrip ini dan mendapatkan hasilnya melalui API Skrip Google Apps, tetapi pertama-tama kami menyiapkan proyek Google kami sesuai dengan itu.
Perhatian: Untuk kenyamanan memahami apa yang terjadi, di bawah ini saya akan merujuk hanya dua halaman, oleh karena itu disarankan untuk membukanya di tab yang berdekatan:
- Halaman Skrip / Penyuntingan Script - “Halaman 1”
- Google Cloud Platform Page - “Halaman 2”
LANGKAH 3. Konfigurasikan Platform Google Cloud
Kami pergi ke Google Cloud Platform (halaman 2), membuat proyek baru. Diperlukan untuk membuat proyek baru, karena secara default status proyek adalah Default, dan Standart diperlukan untuk tujuan kita. Rincian lebih lanjut dapat ditemukan di
sini (poin 3).
Kami kembali ke halaman 2, buka tab "API dan Layanan", lalu "Jendela Permintaan Akses OAuth". Setel Jenis Pengguna ke "Eksternal."
Di jendela yang muncul, isi "Nama Aplikasi".
Buka halaman beranda di Google Cloud Platform. Dari blok "Informasi Proyek" salin nomor proyek.
Pergi ke halaman 1. Buka skrip yang dibuat sebelumnya. Di jendela pengeditan skrip yang dibuka, buka "Sumber Daya" -> "proyek Platform Cloud". Di bidang "Ubah proyek", masukkan nomor proyek yang sebelumnya disalin. Sekarang skrip ini dikaitkan dengan proyek yang dibuat.
LANGKAH 4. API Python REST
Saatnya untuk mengotomatiskan skrip menggunakan
REST API . Python digunakan sebagai bahasa.
Login API Aplikasi Script
Kode harus memiliki akses ke proyek, sehingga prosedur pertama dan yang sangat penting adalah login di API Script Aplikasi. Buka halaman 2 -> "API dan Layanan" -> "Kredensial" -> "Buat Kredensial" -> "Pengidentifikasi Klien OAuth" -> "Jenis Lain". Kami memanggil pengidentifikasi kami, buka. Berada di tab "Kredensial", pilih "Unduh file JSON." Ini akan memuat file kunci untuk akses dari kode ke proyek di Google. Kami menempatkan file ini di folder kredensial.
Sekarang Anda perlu memberikan izin untuk menggunakan API (dalam kasus kami, API Skrip Aplikasi) sebagai bagian dari proyek ini. Untuk melakukan ini, buka "API dan Layanan" -> "Perpustakaan" -> ketik "Apps Script API" dalam pencarian dan klik "Aktifkan".
Aplikasi yang berinteraksi dengan Google memiliki banyak izin yang harus diberikan pengguna saat meluncurkannya. Salinan ini tergantung pada fungsi yang digunakan oleh skrip tertentu dan Anda dapat menemukannya dengan membuka halaman 1 di jendela pengeditan skrip di “File” -> “Project Properties” -> “Scopes”. Izin ini harus disimpan untuk digunakan di masa depan dalam kode.
Dalam hal ini, fungsi login akan terlihat seperti ini:
import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request def login(config): try: creds = None
Blok kode ini adalah prosedur standar untuk memulai dengan Google App Script.
Kami menggunakan token otentikasi dan, dengan masuk, baik membuat token baru atau menggunakan yang sudah ada.
Untuk kenyamanan, file konfigurasi JSON dibuat, yang memiliki bentuk berikut:
{ "SCOPES": ["https://www.googleapis.com/auth/forms", "https://www.googleapis.com/auth/script.send_mail"], "credentials_path": "credentials/", "credentials_file": "google_test_project.json", "token_file": "token.pickle" }
Penting: token dibuat untuk otentikasi dengan ruang lingkup izin khusus. Dengan kata lain, saat mengubah ruang lingkup izin, Anda harus menghapus token dan membuat token baru saat login.
Kode skrip pembaruan jarak jauh
Sekarang kita akan belajar cara memperbarui kode skrip dari jarak jauh, kemudian jalankan kode ini dan dapatkan hasilnya. Bahkan, selain kode yang kami jalankan di editor Google, ada juga
file manifes yang berisi hak peluncuran, pengaturan penempatan, dll. Informasi lebih lanjut tentang strukturnya dapat ditemukan di
sini .
Untuk melihat file manifes default yang dibuat oleh Google untuk skrip Anda, buka editor skrip di "Lihat" -> "Tampilkan file manifes". Manifes akan muncul di daftar file yang terkait dengan skrip ini.
Pidato tentang manifes bukan tanpa alasan: pembaruan skrip jarak jauh memerlukan pengunduhan kode kedua file (* .gs) dan manifes (appscript.json).
Pertama, baca kode file .gs yang ingin kita gunakan:
with open('export-google-form.gs', 'r') as f: sample_code = f.read()
Sekarang salin manifes yang dibuat secara otomatis dan modifikasi sedikit untuk keperluan kita. Dokumentasinya cukup komprehensif menggambarkan struktur file manifes, jadi saya tidak akan membahas hal ini. Agar skrip berfungsi, Anda perlu menambahkan bagian "executionApi" ke manifes default, yang diperlukan untuk menjalankan skrip dari jarak jauh melalui API. Di bagian ini kami menunjukkan lingkaran orang yang memiliki kemampuan untuk menjalankannya. Saya telah mengizinkan peluncuran untuk semua yang telah lulus otorisasi, yang sesuai dengan pengidentifikasi "SIAPA PUN":
MANIFEST = ''' { "timeZone": "America/New_York", "exceptionLogging": "STACKDRIVER", "executionApi": { "access": "ANYONE" } } '''.strip()
Badan permintaan pembaruan harus berisi larik file dengan struktur berikut:
- name : nama file yang akan dibuat di server, tanpa ekstensi
- ketik : jenis file (JSON untuk manifes, SERVER_JS untuk .gs)
- sumber : kode file
request = { 'files': [{ 'name': 'hello', 'type': 'SERVER_JS', 'source': sample_code }, { 'name': 'appsscript', 'type': 'JSON', 'source': MANIFEST } ] }
Akhirnya, permintaan pembaruan itu sendiri harus berisi isi (permintaan yang dijelaskan di atas) dan ID skrip. Yang terakhir dapat diperoleh dengan pergi ke "File" -> "Project Properties" di editor skrip dan menyalin "Script ID":
script_id = 'qwertyuiopQWERTYUIOPasdfghjkl123456789zxcvbnmASDFGHJKL54'
Untuk objek layanan yang diperoleh sebagai hasil dari login, kami mendapatkan bidang project () dan memanggil metode updateContent (), setelah itu kami memanggil metode execute () untuk objek HttpRequest yang diterima:
service.projects().updateContent( body=request, scriptId=script_id ).execute()
Namun, untuk saat ini, menjalankan kode akan menghasilkan kesalahan:
"error": { "code": 403, "message": "Request had insufficient authentication scopes.", "status": "PERMISSION_DENIED" }
Seperti yang Anda lihat, tidak ada cukup izin dalam osprey otentikasi, yang telah kami sebutkan sebelumnya. Kami beralih ke dokumentasi resmi tentang API, yaitu metode
updateContent , yang kami gunakan untuk memperbarui skrip dari jarak jauh. Dokumentasi mengatakan bahwa menggunakan metode ini memerlukan akses yang memungkinkan ke script.projects:
https://www.googleapis.com/auth/script.projects
Tambahkan ke file konfigurasi kami di bagian RUANG LINGKUP. Seperti yang saya tulis di atas, ketika mengubah osprey, perlu untuk menghapus token yang dihasilkan secara otomatis.
Hebat! Saat ini, kami telah belajar memperbarui skrip Google dari jarak jauh. Tetap menjalankannya dan mendapatkan hasil eksekusi.
Jalankan skrip
Permintaan
peluncuran skrip berisi skripID dan isi dengan struktur berikut:
- function : nama fungsi yang ingin kita jalankan
- parameter : (opsional) satu set parameter dari tipe primitif (string, array ...) diteruskan ke fungsi
- sessionState : (opsional) hanya diperlukan untuk aplikasi Android
- devMode : (opsional) Benar jika pengguna adalah pemilik skrip dan kemudian versi terbaru akan diluncurkan daripada yang digunakan menggunakan Apps Script API. (secara default - Salah)
Agar tidak menjahit URL formulir Google di skrip, kami akan meneruskan
form_url ke fungsi
utama sebagai argumen.
Perhatian Saat kami menguji skrip, fungsi
utama tidak menerima apa pun, jadi kami akan mengubah baris kode pertama dalam file .gs sebagai berikut:
function main(form_url) { var form = FormApp.openByUrl(form_url); .......
Karena aplikasi kami bukan untuk Android dan kami adalah pemilik skrip, maka tubuh akan terlihat seperti ini:
body = { "function": "main", "devMode": True, "parameters": form_url }
Jalankan skrip dan tulis hasil eksekusi ke variabel resp:
resp = service.scripts().run(scriptId=script_id, body=body).execute()
Simpan resp ke file dengan pemformatan JSON yang nyaman:
import json with open('habr_auto.json', 'w', encoding='utf-8') as f: json.dump(resp['response']['result'], f, ensure_ascii=False, indent=4)
Perhatian Karena kenyataan bahwa permintaan script.run () sedang menunggu hasil melalui soket, ketika batas waktu terlampaui oleh waktu eksekusi, kesalahan dari tipe berikut akan terjadi:
socket.timeout: The read operation timed out
Untuk menghindari perilaku ini, saya sarankan bahwa pada awal program menetapkan batas waktu soket terbuka, jelas cukup untuk menunggu skrip untuk menyelesaikan eksekusi. Dalam kasus saya, 120 detik sudah cukup:
import socket socket.setdefaulttimeout(120)
Voila! Jalur pipa yang nyaman untuk memperbarui dan meluncurkan skrip Google dari jarak jauh sudah siap. Kode lengkap yang diadaptasi untuk peluncuran dari terminal diberikan di
github saya.
Juga, saya akan memberikan kode fungsi utama di bawah ini
login.py from pprint import pprint import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request def login(config): try: creds = None
update_script.py from pprint import pprint import json import sys from googleapiclient import errors from google_habr_login import login MANIFEST = ''' { "timeZone": "America/New_York", "exceptionLogging": "STACKDRIVER", "executionApi": { "access": "ANYONE" } } '''.strip() def update_project(service, script_id, script_file_name):
export_form.py from pprint import pprint import socket import json import sys from googleapiclient import errors from google_habr_login import login socket.setdefaulttimeout(120)
Untuk memulai, Anda harus meletakkan file JSON dengan kunci akses Google di folder kredensial, dan konfigurasi JSON di direktori yang sama dengan skrip.
Kemudian, jika kita ingin memperbarui skrip dari jarak jauh, maka dalam panggilan terminal:
python update_script.py <config_file_name> <script_id> <script_file_name>
Dalam hal ini:
- config_file_name - nama file JSON konfigurasi
- script_id - ID skrip
- script_file_name - nama file .gs yang akan diunggah ke google
Untuk menjalankan skrip, hubungi:
python export_form.py <config_file_name> <result_file_name> <script_id> <google_form_url>
Dalam hal ini:
- config_file_name - nama file JSON konfigurasi
- result_file_name - nama file JSON di mana formulir akan dibongkar
- script_id - ID skrip
- google_form_url - google form url
Terima kasih atas perhatian Anda, menunggu saran dan komentar Anda :)