반응형


    서버를 가지고 운영하는 웹사이트는 데이터베이스(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 뭐하라