// -*- coding: utf-8 -*- const fs = require('fs').promises; const path = require('path'); const process = require('process'); const {authenticate} = require('@google-cloud/local-auth'); const {google} = require('googleapis'); const puppeteer = require('puppeteer'); // --- 設定項目 --- // Google APIのスコープ。今回は読み取り専用 const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly']; // 認証情報ファイルのパス const TOKEN_PATH = path.join(process.cwd(), 'token.json'); const CREDENTIALS_PATH = path.join(process.cwd(), 'credentials.json'); // 読み込むスプレッドシートのID const SPREADSHEET_ID = "1aFlOX5mk0ELARP4K8NIJbj99A8zZN06Z0isRGIP_Gw"; // 読み込むシート名と範囲 (A列からJ列まで読み込みます) const RANGE_NAME = "sheet01!A:J"; // ログインページのベースURL const BASE_URL = "http://www.esod-neo.com/client_certify_to_logon.php?id="; /** * 認証情報を読み込むか、ない場合は新規に認証する関数 */ async function authorize() { let client = await loadSavedCredentialsIfExist(); if (client) { return client; } client = await authenticate({ scopes: SCOPES, keyfilePath: CREDENTIALS_PATH, }); if (client.credentials) { await saveCredentials(client); } return client; } async function loadSavedCredentialsIfExist() { try { const content = await fs.readFile(TOKEN_PATH); const credentials = JSON.parse(content); return google.auth.fromJSON(credentials); } catch (err) { return null; } } async function saveCredentials(client) { const content = await fs.readFile(CREDENTIALS_PATH); const keys = JSON.parse(content); const key = keys.installed || keys.web; const payload = JSON.stringify({ type: 'authorized_user', client_id: key.client_id, client_secret: key.client_secret, refresh_token: client.credentials.refresh_token, }); await fs.writeFile(TOKEN_PATH, payload); } /** * メインの処理を実行する関数 */ async function main(auth) { const sheets = google.sheets({version: 'v4', auth}); // スプレッドシートからデータを取得 let res; try { res = await sheets.spreadsheets.values.get({ spreadsheetId: SPREADSHEET_ID, range: RANGE_NAME, }); } catch (err) { console.log(`Google APIエラーが発生しました: ${err}`); return; } const values = res.data.values; if (!values || values.length === 0) { console.log('スプレッドシートからデータが見つかりませんでした。'); return; } console.log("スプレッドシートからデータを取得しました。処理を開始します。"); // 処理対象のレコードを抽出 const records_to_process = []; let processing_started = false; for (const row of values) { if (row.length < 10) continue; const col_a = row[0] ? row[0].trim() : ''; if (col_a === '終了') { break; } if (processing_started) { const login_id = row[3] ? row[3].trim() : ''; const password = row[4] ? row[4].trim() : ''; const url_id = row[9] ? row[9].trim() : ''; if (login_id && password && url_id) { records_to_process.push({ login_id, password, url_id }); } } if (col_a === '開始') { processing_started = true; } } if (records_to_process.length === 0) { console.log("処理対象のレコードが見つかりませんでした。「開始」と「終了」の間にデータがあるか確認してください。"); return; } console.log(`${records_to_process.length}件のレコードを処理します。`); // 各レコードに対してブラウザ操作を実行 for (let i = 0; i < records_to_process.length; i++) { const record = records_to_process[i]; console.log(`--- ${i + 1}件目の処理を開始: ID ${record.login_id} ---`); const browser = await puppeteer.launch({ headless: false }); // headless: falseでブラウザの動きが見えます const page = await browser.newPage(); try { const full_url = BASE_URL + record.url_id; console.log(`URLを開いています: ${full_url}`); await page.goto(full_url); // ページが完全に読み込まれるのを待つ await page.waitForSelector('#id', { timeout: 10000 }); // IDとパスワードを入力 console.log("ログインIDを入力しました。"); await page.type('#id', record.login_id); console.log("パスワードを入力しました。"); await page.type('#password', record.password); // ログインボタンをクリック console.log("ログインボタンをクリックしました。"); await page.click("input[type='submit']"); console.log("ログイン後のページ読み込みを待っています..."); await new Promise(resolve => setTimeout(resolve, 5000)); console.log("処理が完了しました。"); } catch (e) { console.error(`エラーが発生しました: ${e.message}`); } finally { await browser.close(); console.log("ブラウザを閉じました。"); console.log("-".repeat(20)); } } console.log("すべての処理が完了しました。"); } // 認証を実行してメイン関数を呼び出す authorize().then(main).catch(console.error);