Next.js: собираем данные с формы в Google spreadsheet

Представьте, что вам нужно быстро сделать новый лендинг на котором нужно собрать какую-либо информацию с клиентов. Можно, конечно, воспользоваться API каких-то CRM системами, но это потребует время. Самым простым и быстром вариантом будет использование Google Spreadsheet в связке с Next.js.


Для создания лендингов с формами очень хорошо подходит Next.js потому что разворачивается очень быстро, а использование React и Typescript позволяет быстро создавать или использовать любые компоненты с минимум ошибок. В тоже время Google Spreadsheet уже имеет хороший UI интерфейс и множество операций данными полученных через формы.

Первым шагом вам нужно создать Service Account  вот на этой странице https://console.cloud.google.com/. Как это сделать хорошо написано вот по этому адресу https://developers.google.com/identity/protocols/oauth2/service-account?hl=ru. После всех проделанных действий на выходе вы получите JSON файл с данными для доступа.

Следующим шагом необходимо установить библиотеку  https://www.npmjs.com/package/google-spreadsheet. Это достаточной хороший компонент для работы с таблицами из nodejs. Если вы используете Typescript то вам нужно будет установить еще типы для этой библиотеки @types/google-spreadsheet.

npm i google-spreadsheet --save
npm i @types/google-spreadsheet --save-dev

Теперь необходимо приступить к написанию кода для получения даных с формы и отправки в Google Spreadsheet. Не забудьте подставить правильный ID документа который можно взять из URL документа открытой страницы в Google Spreadsheet. А также нужно добавить разрешение на Запись в файл для email указанного в JSON файле с данными авторизации.

import { GoogleSpreadsheet } from 'google-spreadsheet';
import type { NextApiRequest, NextApiResponse } from 'next';
import { FieldSchemaValues } from '../../blocks/index/form';
import creds from '../../config/nodejs.json';

const doc = new GoogleSpreadsheet('<ID документа Google spreadsheet>');
export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
) {
    if (req.method !== 'POST') {
        return res.status(405).json({
            error: 'Incorrect form request'
        });
    }
    
    // Получаем данных из запроса с формы
    const {
        name,
        email,
        instagram,
        tiktok,
        youtube
    }: FieldSchemaValues = req.body;
    
    // Валидируем данные
    if (!name || !email) {
        return res.status(400).json({
            error: 'Please provide name & email'
        });
    }
    
    // Авторизируем наш новый клиент
    await doc.useServiceAccountAuth(creds);
    await doc.loadInfo();
    const date = new Date().toUTCString();
    const sheet = await doc.sheetsByIndex[0];
    
    // Добавляем заголовки столбцов
    await sheet.setHeaderRow([
       'Date',
       'Name',
       'Email',
       'Instagram',
       'TikTok',
       'Youtube',
    ]);
    
    // Пишем данные в фаил
    await sheet.addRow({
        Date: date,
        Name: name,
        Email: email,
        Instagram: String(instagram),
        TikTok: String(tiktok),
        Youtube: String(youtube),
    });
    return res.status(200).json({});
}

На этом все. Вы так же можете добавить уже дополнительно капчу или какие-то другие способы валидации по желанию. Кроме того вы можете использовать этот сервисный аккаунт уже для сбора данных с других форм или даже в других проектах.