Framer에서 구글 시트로 데이터 전송하기

2023. 8. 29. 11:20·코드와 오류 기록

어쩌다보니 프레이머에 code component를 만들게 되었는데, 어차피 만든 김에 구글 시트에 바로 정보를 쏘면 다른 써드파티 서비스를 추가로 결제하지 않아도 될 것 같다는 생각이 들었다. (게다가 대부분의 폼 서비스가 submission 단위로 결제를 요구하니 부담스럽기도 했다.)

 

일단 신청 폼을 만들고 제출 버튼을 누르면 완료 팝업이 뜨게끔 코드를 작성하고, 구글 스크립트에 doPost() 함수를 만들어 웹 서비스 배포를 했다.

// Welcome to Code in Framer
// Get Started: https://www.framer.com/developers/

import React, { useState, useEffect } from "react"
import Example from "https://framer.com/m/framer/Example.js@^1.0.0"

// Modal component
const Modal = ({ message, onClose }) => {
    return (
        <div
            style={{
                position: "fixed",
                top: 0,
                left: 0,
                width: "100%",
                height: "100%",
                background: "rgba(0, 0, 0, 0.5)",
                display: "flex",
                zIndex: 9999,
                alignItems: "center",
                justifyContent: "center",
            }}
        >
            <div
                style={{
                    background: "white",
                    padding: "30px",
                    borderRadius: "8px",
                    boxShadow: "0 2px 8px rgba(0, 0, 0, 0.1)",
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    zIndex: 10000,
                }}
            >
                <p>{message}</p>
                <button
                    onClick={onClose}
                    style={{
                        width: "140px",
                        background: "#111111",
                        color: "white",
                        padding: "8px 16px",
                        border: "none",
                        borderRadius: "4px",
                        cursor: "pointer",
                        marginTop: "12px",
                    }}
                >
                    확인
                </button>
            </div>
        </div>
    )
}

export default function Form(props) {
    const [isModalVisible, setIsModalVisible] = useState(false)

    const handleSubmit = async (event) => {
        event.preventDefault()
        const nameInput = document.getElementById("name") as HTMLInputElement
        const phoneInput = document.getElementById("number") as HTMLInputElement
        const addressTextarea = document.getElementById(
            "message"
        ) as HTMLTextAreaElement

        const formData = {
            name: nameInput.value,
            phone: phoneInput.value,
            address: addressTextarea.value,
        }

        const response = await fetch(
            "GOOGLE_APPS_SCRIPT_WEBAPP_URL",
            {
                method: "POST",
                mode: "no-cors",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(formData),
            }
        )
        setIsModalVisible(true)
    }

    const handleKeyboardOpen = () => {
        const viewportMeta = document.querySelector(
            'meta[name="viewport"]'
        ) as HTMLMetaElement
        if (viewportMeta) {
            viewportMeta.content =
                "width=device-width, initial-scale=1, maximum-scale=1"
        }
    }

    const handleKeyboardClose = () => {
        const viewportMeta = document.querySelector(
            'meta[name="viewport"]'
        ) as HTMLMetaElement
        if (viewportMeta) {
            viewportMeta.content =
                "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
        }
    }

    useEffect(() => {
        window.addEventListener("resize", handleKeyboardOpen)
        window.addEventListener("orientationchange", handleKeyboardOpen)
        window.addEventListener("focusin", handleKeyboardOpen)
        window.addEventListener("focusout", handleKeyboardClose)

        return () => {
            window.removeEventListener("resize", handleKeyboardOpen)
            window.removeEventListener("orientationchange", handleKeyboardOpen)
            window.removeEventListener("focusin", handleKeyboardOpen)
            window.removeEventListener("focusout", handleKeyboardClose)
        }
    }, [])

    return (
        <div>
            <form
                style={{
                    display: "flex",
                    flexDirection: "column",
                    alignItems: "center",
                    fontFamily: "Inter, sans-serif",
                    fontSize: "18px",
                    color: "RED",
                    padding: "24px",
                    backgroundColor: "white",
                    borderRadius: "8px",
                    boxShadow: "0 0 8px 0 rgba(0, 0, 0, 0.0)",
                }}
                onSubmit={handleSubmit}
            >
                <input
                    type="text"
                    id="name"
                    name="name"
                    placeholder="1.입력란"
                    required
                    style={{
                        width: "100%",
                        padding: "16px",
                        marginBottom: "12px",
                        border: "1px solid #ccc",
                        borderRadius: "8px",
                    }}
                />
                <input
                    type="text"
                    id="number"
                    name="phone"
                    placeholder="2.입력란"
                    required
                    style={{
                        width: "100%",
                        padding: "16px",
                        marginBottom: "12px",
                        border: "1px solid #ccc",
                        borderRadius: "8px",
                    }}
                />
                <textarea
                    type="textarea"
                    rows="4"
                    id="message"
                    name="message"
                    placeholder="3.입력란"
                    required
                    style={{
                        width: "100%",
                        padding: "16px",
                        marginBottom: "12px",
                        border: "1px solid #ccc",
                        borderRadius: "8px",
                    }}
                />
                <input
                    type="submit"
                    value="제출"
                    style={{
                        fontSize: "16px",
                        fontFamily: "Manrope, sans serif",
                        width: "100%",
                        padding: "16px",
                        backgroundColor: "#111111",
                        color: "white",
                        fontWeight: "bold",
                        border: "none",
                        borderRadius: "8px",
                        cursor: "pointer",
                    }}
                />
                <p
                    style={{
                        fontFamily: "Manrope, sans-serif",
                        fontWeight: "500",
                        color: "#666666",
                        fontSize: "9px",
                        lineHeight: "1.5",
                        textAlign: "left",
                        marginTop: "8px", // Add some space from the button
                    }}
                >
                    덧붙이고 싶은 라벨은 여기에
                </p>
            </form>
            {isModalVisible && (
                <Modal
                    message="팝업 메세지 입력하기"
                    onClose={() => setIsModalVisible(false)}
                />
            )}
        </div>
    )
}

// Styles are written in object syntax
// Learn more: https://reactjs.org/docs/dom-elements.html#style
const containerStyle = {
    height: "100%",
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    overflow: "hidden",
}

그리고 구글 스크립트에 아래의 함수를 만들면 POST 요청에 따라 doPost 함수가 호출된다. 이때 배포 과정을 꼭 거쳐야 한다. SHEET_ID는 구글 스프레드 시트 URL 뒷 부분에 자리한 값이다.

function doPost(e) {
  var sheet = SpreadsheetApp.openById('SHEET_ID').getActiveSheet();
  var data = JSON.parse(e.postData.contents);
  var row = [new Date(), data.name, data.phone, data.address];
  sheet.appendRow(row);  

  return ContentService.createTextOutput('Success').setMimeType(ContentService.MimeType.TEXT);
}

 

여기까지 완료되면 각각의 코드의 GOOGLE_APPS_SCRIPT_WEBAPP_URL 를 넣어주면 끝난다.

저작자표시 비영리 변경금지 (새창열림)

'코드와 오류 기록' 카테고리의 다른 글

git push RPC failed disconnect while reading sideband packet  (0) 2024.08.20
Framer에서 OS별로 버튼 출력여부 결정하기  (0) 2023.08.29
pytorch를 이용한 운동 자세 확인  (0) 2023.08.15
SD roop 설정  (0) 2023.08.10
SD pip install 수동으로 해주기  (1) 2023.08.10
'코드와 오류 기록' 카테고리의 다른 글
  • git push RPC failed disconnect while reading sideband packet
  • Framer에서 OS별로 버튼 출력여부 결정하기
  • pytorch를 이용한 운동 자세 확인
  • SD roop 설정
신사(SinSa)
신사(SinSa)
#취미 사진가 #IT 직장인 경험하고 배운 것들을 글로, 사진으로 기록하고 있어요
  • 신사(SinSa)
    신사(SinSa)
    신사(SinSa)
  • 전체
    오늘
    어제
    • View all (425)
      • 잡념과 생각 (104)
      • 코드와 오류 기록 (80)
      • 사진 이야기 (10)
      • 교육과 육아 (12)
      • Brand (2)
      • 자료 모음 (46)
      • 축구 이야기(deprecated) (171)
  • 블로그 메뉴

    • 홈
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    국가대표팀 감독
    맨유
    박주영
    축구협회
    승강제
    한국 축구
    국가대표팀
    Product Manager
    프로덕트오너
    Product Owner
    fc서울
    대한축구협회
    스타트업
    아이폰 게임
    홍명보호
    경남FC
    프로덕트 매니저
    프로축구
    김주영
    한국축구
    쿠웨이트전
    아스날
    프로덕트 오너
    k리그
    축구
    애자일
    PM
    아이폰 축구게임
    대치키즈
    Po
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
신사(SinSa)
Framer에서 구글 시트로 데이터 전송하기
상단으로

티스토리툴바