서버를 가지고 운영하는 웹사이트는 데이터베이스(db)를 가지고 각종 정보를 기록하고 읽어들일 수 있습니다. 게시판, 댓글, 회원정보 등 모두 db에 저장되고 불러와집니다.


    그러나 티스토리는 서비스형 블로그이기 때문에, 데이터베이스에 접근할 수 없고, 그것을 활용할 수도 없습니다.



    작은 크기의 데이터에 한정된 이야기지만, 구글드라이브에서 서비스하고있는 구글 스프레드시트(google spreadsheet)를 마치 데이터베이스 처럼 사용할 수 있는 방법이 있습니다.


    구글 스프레드시트는 무료이며, 따로 용량제한은 없고 총 40만셀, 256열까지 기록이 가능합니다.

    또한 api를 제공하기 때문에 클라우드DB로 사용하기 적합합니다. (물론 SQL을 사용할 수 없지만..)


    접근할 수 있는 데이터베이스를 가짐으로서 응용할 수 있는 가능성은 무궁무진합니다.

    접속할 때마다 페이지경로를 저장해서 포스트당 조회수도 판단할 수 있고,

    오류페이지가 있을 때, 기록해서 어느 포스트에 오류가 있는지 찾을 수도 있습니다.

    방명록이 아닌, '문의하기'를 만들 수도 있습니다.


    이번 포스트에서는 그 시작으로 구글 스프레드시트에 ajax를 통해 '기록'하는 방법을 알아보겠습니다.



    다음 문서에서 많은 참조를 했습니다.

    http://mashe.hawksey.info/2014/07/google-sheets-as-a-database-insert-with-apps-script-using-postget-methods-with-ajax-example/




    준비물

    DB로 사용 할 구글 스프레드시트

    -구글 드라이브에 접속하여 '만들기' - '스프레드시트'



    구글 스프레드시트가 ajax 요청을 받을 수 있도록 app script 작성하기


    준비한 스프레드시트에서 도구-스크립트 편집기로 들어갑니다.



    빈프로젝트를 선택합니다.



    원래 있던 내용은 모두 삭제하고, 다음 내용을 붙여넣습니다.


    //  1. Enter sheet name where data is to be written below

            var SHEET_NAME = "시트1";

             

    //  2. Run > setup

    //

    //  3. Publish > Deploy as web app

    //    - enter Project Version name and click 'Save New Version'

    //    - set security level and enable service (most likely execute as 'me' and access 'anyone, even anonymously)

    //

    //  4. Copy the 'Current web app URL' and post this in your form/script action

    //

    //  5. Insert column names on your destination sheet matching the parameter names of the data you are passing in (exactly matching case)

     

    var SCRIPT_PROP = PropertiesService.getScriptProperties(); // new property service

     

    // If you don't want to expose either GET or POST methods you can comment out the appropriate function

    function doGet(e){

      return handleResponse(e);

    }

     

    function doPost(e){

      return handleResponse(e);

    }

     

    function handleResponse(e) {

      // shortly after my original solution Google announced the LockService[1]

      // this prevents concurrent access overwritting data

      // [1] http://googleappsdeveloper.blogspot.co.uk/2011/10/concurrency-and-google-apps-script.html

      // we want a public lock, one that locks for all invocations

      var lock = LockService.getPublicLock();

      lock.waitLock(30000);  // wait 30 seconds before conceding defeat.

       

      try {

        // next set where we write the data - you could write to multiple/alternate destinations

        var doc = SpreadsheetApp.openById(SCRIPT_PROP.getProperty("key"));

        var sheet = doc.getSheetByName(SHEET_NAME);

         

        // we'll assume header is in row 1 but you can override with header_row in GET/POST data

        var headRow = e.parameter.header_row || 1;

        var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];

        var nextRow = sheet.getLastRow()+1; // get next row

        var row = [];

        // loop through the header columns

        for (i in headers){

          if (headers[i] == "Timestamp"){ // special case if you include a 'Timestamp' column

            row.push(new Date());

          } else { // else use header name to get data

            row.push(e.parameter[headers[i]]);

          }

        }

        // more efficient to set values as [][] array than individually

        sheet.getRange(nextRow, 1, 1, row.length).setValues([row]);

        // return json success results

        return ContentService

              .createTextOutput(JSON.stringify({"result":"success", "row": nextRow}))

              .setMimeType(ContentService.MimeType.JSON);

      } catch(e){

        // if error return this

        return ContentService

              .createTextOutput(JSON.stringify({"result":"error", "error": e}))

              .setMimeType(ContentService.MimeType.JSON);

      } finally { //release lock

        lock.releaseLock();

      }

    }

     

    function setup() {

        var doc = SpreadsheetApp.getActiveSpreadsheet();

        SCRIPT_PROP.setProperty("key", doc.getId());

    }

    파란색으로 표시한 시트1은 스프레드시트에서 ajax요청을 기록할 시트 이름입니다. 따로 변경하지 않았으면 그대로 두시면 됩니다.



    디스켓모양 버튼을 눌러 스크립트를 저장합니다. 프로젝트 이름은 마음대로 정하시면 됩니다.


    저장이 되었으면, 실행-setup을 선택합니다.


    그러면 인증을 요청하고 


    동의를 눌러줍니다.


    동의 후에 setup을 한번 더 실행해줍니다.



    마지막 단계로 저장한 스크립트를 웹앱으로 배포해야합니다.

    게시-웹 앱으로 배포를 선택합니다.


    프로젝트 버전은 오른쪽에 새버전저장 버튼을 누르시고,

    앱을 실행할 사용자는 '나',

    웹에 액세스 할 수 있는 사용자는 누구나(익명 포함)으로 선택해주세요.


    마치면 웹앱 URL이 발급되고, 스크립트가 ajax 요청을 받을 준비가 되었습니다.


    웹 앱 URL을 복사해두세요!


    ※추후 스크립트 내용을 수정하는 경우 (시트 이름 변경 등)

    저장 → 실행-setup게시 -업데이트 3단계를 순서대로 수행해야 적용됩니다.



    .


    ajax 를 통해 구글 스프레드시트에 기록하는 방법

    이제 위에서 복하새둔 웹 앱 URL을 통해 ajax GET/POST 요청을 보낼 수 있습니다.

    ajax명령어를 사용하려면 skin.html에 jQuery스크립트를 포함해야합니다.

    예)<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>



    url은 복사해둔 웹앱 URL을 사용하면 됩니다.


    다음은 ajax 예제입니다.

    $.ajax({

      url: "웹앱URL",

      data: {A:"a", B:"b"},

      type: "POST"

    });

    (스프레드시트에는 미리 첫번째 행에 A가 기록된 열과 B가 기록된 열이 존재해야 a, b가 기록됩니다.)



    크롬 개발자도구 콘솔로 연습을 해봅니다.

    스프레드 시트에 미리 A,B로 헤더를 만들어 놓은 뒤

    ajax 요청을 보내봅니다.

    (data에 들어간 A:"a"에서 A는 A열이라서가 아니라 1행에 있는 A를 의미합니다. 만약A1에 test1이라고 적혀있다면 data도 test1:"1" 이어야 합니다.)


    정상적으로 A열에 a가, B열에 b가 기록된 것을 확인할 수 있습니다.



    웹앱으로 만든 스크립트에는 기본적으로 Timestamp를 기록하는 함수가 포함되어있습니다.

    Timestamp라는 열을 만들어두면, 따로 data를 작성하지 않아도 요청 시각이 기록됩니다.



    자바스크립트, jQuery, ajax에 능통하신 분들은 벌써부터 무엇에 응용하면 좋을 것인지 생각하고 계실듯 합니다.

    저 역시 전문가는 아니지만, 앞으로 차근차근 초보자분들도 따라하실 수 있도록 강좌를 올려보도록 하겠습니다.


    다음편은 티스토리 방문자 기록 편 입니다.

    구글 스프레드시트를 데이터베이스로 이용하기 - 2.방문로그 기록 편


    Posted by 뭐하라

    문제가 있나요?(?)

    내용상 오류가 있음 업데이트 필요 화면이 깨짐 기타 수정이 필요함
    • BlogIcon aquaani
      2015.05.08 15:04 신고

      좋은글 잘보고 갑니다.
      한가지 궁금한게 있습니다.
      $.ajax({ 을 입력하는곳이 문서 어느부분쯤에 입력을 해야 하나요.
      만약 HTML에서 라고 보면, 어느부분에 입력을 하는건지 여쭤보는 겁니다.

      • BlogIcon 뭐하라
        2015.05.08 22:05 신고

        html이 아니라 자바스크립트구문이고
        <script> 태그로 둘러싸서 아무곳에나 들어가도됩니다. 보통은 </body>위에 넣죠


    • 2015.11.29 17:11

      비밀댓글입니다

      • BlogIcon 뭐하라
        2015.11.29 22:10 신고

        아 그건 서식만 바꿔주시면 됩니다
        스프레드시트에서 A열을 선택한다음에 서식-숫자-날짜시간으로 고쳐주시면 돼요~^^


      • 2015.11.29 22:42

        비밀댓글입니다

      • BlogIcon 뭐하라
        2015.11.29 23:14 신고

        http://nubiz.tistory.com/542
        여기 삭제함수가 포함되어있는데 수정도 가능할것같네요.
        구글스크립트 파고든지 너무 오래되서 기억이 안납니다 ㅠㅠ

        자바스크립트를 이용하시려면 좀더 복잡할거같은데.. 구글스크립트로 수정함수, 삭제함수를 작성하셔서 post받는 방식으로 사용하시면 될거같습니다만.. 복잡하네요

      • BlogIcon Mir(whdghks913)
        2015.11.30 00:07 신고

        감사합니다~

    • BlogIcon 도파민
      2016.02.21 13:16 신고

      안녕하세요~ 저도 비슷하게 며칠째 ajax 이용해서 웹사이트&티스토리와 구글 스프레드시트간 데이터 전송을 시도하고 있습니다.
      저는 똑같이 해도 Cross-Origin 문제때문에 요청이 전송이 되지 않습니다. 혹시 따로 CORS 처리를 하신 부분이 있나요?

      • BlogIcon 뭐하라
        2016.02.22 21:09 신고

        웹앱 주소는 크로스도메인문제가 발생하지 않습니다
        본문내용에서 빠뜨린점이 없는지 잘 확인해보세요

    • BlogIcon 칠층첫째
      2016.02.23 20:18 신고

      감사합니다. 파일을 지우고 다시 해보니 잘 되네요.
      개인적으로 필요한 부분에 참고해서 유용히 쓰겠습니다~

    • BlogIcon 뜨아
      2016.04.15 16:06 신고

      유용한 정보 감사합니다~
      테스트 중인데 잘 작동하는군요~

    • BlogIcon RootKR
      2016.07.27 16:38 신고

      이런 비슷한 기능 찾다가 발견하고 잘 적용했네요...

      만들어주셔서 감사합니다 ^^

    • gze1206
      2017.01.18 18:22 신고

      값이 undefined라고만 들어가는 것 같은데 혹시 왜 이러는건지 아시나요...

      • BlogIcon 뭐하라
        2017.01.18 18:26 신고

        아마도 따옴표를 넣지 않으셨을것 같네요

    • wdb
      2017.01.23 17:10 신고

      data: {"A":"add", "B":"ip"} 이렇게 값을 테스트하는데 전부 undefined로 들어가네요
      다른 방법이있을까요?

      • 뭐하라
        2017.01.23 17:41 신고

        점검해보실것은
        {A:"add", B:"ip"}
        이렇게 key부분 따옴표를 제거해보세요.

        그리고 스프레드시트에도 대문자 A,B가 맞는지 확인해보세요.

      • BlogIcon 뭐하라
        2017.01.23 17:49 신고

        그리고 본문 수정이 지금 안되는데
        $.ajax({
        url: "웹앱URL",
        data: {A:"a", B:"b"},
        type: "POST"
        });
        이게 맞는 예제입니다 쉼표빠진곳없는지도 잘점검해보세요

    • BlogIcon RootKR
      2017.12.19 21:34 신고

      안녕하세요.

      이걸 응용하면 덧글 입력 삭제도 가능한가요?

    • 은아
      2018.02.08 15:44 신고

      좋은기능 정말 감사합니다.
      제가 찾고 있던 기능이예요!!

      data : [{A:"a", B:"b"},{A:"c", B:"b"}] 이런식으로 배열로 여러줄을 넘기고 싶은데 이렇게 입력하면 들어가질않네요. 여러행을 입력하고 싶으면 어떻게 하면 되는지 혹시 아시는지요. ㅠㅠ

      이렇게 해야하는데 며칠을 고민해도 안나오네요. 엉엉

      • BlogIcon 뭐하라
        2018.02.08 22:01 신고

        원하시는 작업을하려면 스프레드시트 앱스크립트에서 array를 받을수 있도록 수정해야하는데 제가 앱스크립트를 전부이해한건 아니라서 어려울것같고요,

        데이터를 전송할때 반복문으로 여러번 전송하는편이 낫겠습니다.

        var arr=[{A:"a", B:"b"},{A:"c", B:"b"}];
        for(var i=0,l=arr.length;i<l;i++){
        $.ajax({
        url: "웹앱URL",
        data: arr[i],
        type: "POST"
        });
        }


    • 은아
      2018.02.08 22:55 신고

      맞아요. 저도 앱스크립트 수정하려다가 결국 이렇게 구현했네요. 답변 감사합니다.^^
      그런데 속도가 좀 느린 단점이 있어요 -

티스토리 툴바