프로그래밍/General

구글 설문지 (Google Forms) 완료시 데이터 외부 API로 전송하기

Lou Park 2023. 3. 22. 01:38

구글 설문지를 완료했을때 보상을 주거나, 추가 정보를 처리해야 할 일이 있을 수 있다. 그래서 구글 설문지를 완료하면 외부 API로 데이터를 보내는 방법을 정리해보려한다.

OAuth Scope 추가하기

먼저 더보기 메뉴에서 [스크립트 편집기]로 진입한다.

설문지 화면

외부 API로 요청을 보내기 위해서 아래 scope에 대한 권한이 필요한데, 이것을 정의하려면 appsscript.json을 편집해야한다.

"https://www.googleapis.com/auth/script.external_request"

프로젝트 설정 > 편집기에 [appsscript.json 매니페스트 파일 표시] 체크를 하면 편집기에서 appsscript.json이 생긴 것을 볼 수 있을 것이다.

{
  "timeZone": "Asia/Seoul",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

위와 같이 oauthScope를 하나 추가 해준다. 그럼 준비가 완료되었다!

 

스크립트 작성

이제 유저가 설문지를 체출했을때 트리거할 함수를 작성 해 볼 것이다. 이건 아주 단순한 예시다.

function submit(e) {
    // 응답을 results 배열에 넣음
  const items = e.response.getItemResponses()
  const results = items.map((item) => {
    return {
      id: item.getItem().getId(),
      type: item.getItem().getType(),
      title: item.getItem().getTitle(),
      response: item.getResponse(),
    }
  })

  UrlFetchApp.fetch(`https://your.host/path`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    payload: JSON.stringify({
      form_id: e.source.getId(),
      form_title: e.source.getTitle(),
      results: results,
    })
  })
}

대략 응답은 다음과 같이 올거다.

{
    "form_id":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "form_title": "설문지의 제목"
    "result":[{"id":1689470117,"type":"TEXT","title":"\b항목의제목","response":"항목응답"}]
}

e.source의 경우는 Form 문서를, e.response는 FormResponse 문서를 참조하면 된다.

 

트리거 연결

AppsScript 트리거 탭에 들어가서 트리거 추가를 누르면, 설문지 양식을 열때나 양식을 제출할때 실행할 함수를 설정할 수 있는데, 방금 작성했던 submit 함수를 연결시켜서 저장해준다. [저장]을 눌러 트리거를 세팅해두면 완성이다.

 

혹시나 보낸 요청들이 제대로 전송되지 않아서 디버깅이 필요할때도 트리거 탭에서 해당 트리거에 대한 실행 결과를 볼 수 있으니 참고하면된다.

Trigger 설정 모달

 

유저 고유 데이터를 넘기는 방법 : 미리 채워진 링크

유저 데이터를 직접 유저에게서 입력받을 수도 있지만, 미리 채워진 링크를 통해 필요한 정보가 채워진 채로 넘겨받을 수도 있다. 예를 들어서 특정한 토큰값을 받아와야한다고 해보자.

단답형이 가장 범용적

토큰 값을 받을 수 있는 항목을 먼저 만들어야한다.

  • URL query parameter를 이용하는 방법이다보니 첫번째 페이지에서만 미리채워진 링크가 작동하기 때문에 설문 항목이 길어서 여러 섹션으로 나눠져있더라도 반드시 첫번째 섹션을 활용하라.

더보기 > 미리 채워진 링크 가져오기


그런다음 더보기 메뉴에서 [미리 채워진 링크 가져오기]를 클릭, 이동한 페이지에서 링크 복사하기를 눌러 링크를 복사하게 되면 다음과 같이 설문지 URL뒤에 entry.<ID> Query Parameter 키가 생길것이다.

https://docs.google.com/forms/d/e/..../viewform?usp=pp_url&entry.2137094099=바보

여기에 값을 넣은채로 설문지에 들어오게되면 이렇게 미리 값이 들어가게된다.

제대로 들어갔다!

이 값을 건드리지 말아달라고 추가 설명을 붙여 유저들이 임의로 값을 변경하는 것을 방지하고, 필요하다면 submit 함수에서 추가 작업을 해주면된다. 예를 들면 이렇게!

function submit(e) {
    // 아까 URL에서 봤던 entry. 뒤의 설문항목 ID
    const tokenItemId = 2137094099

  const items = e.response.getItemResponses()
  const results = items.map((item) => {
        const id = item.getItem().getId()
        if (id == tokenItemId) {
                // 이렇게 토큰을 집어올 수 있다.
                const token = item.getItem.getResponse()
        }
    return {
      ...
    }
  })
    // ...
}

 

안드로이드 앱에서 구글 설문 완료했을때 처리?

앱의 WebView에서도 뭔가 응답 제출을 했을때를 얻어오고 싶을 수 있다. 응답을 제출하면 구글 설문지의 URL Path에 formResponse라는 값이, 이미 제출한 상태라면 alreadyresponded라는 값이 들어간다. 이것을 이용하면 된다.

// 구글 설문지인지 체크하는 함수
fun isGoogleFormUrl(uri: Uri): Boolean {
    if (uri.host == "forms.gle") {
        return true
    }
    return uri.host == "docs.google.com" && uri.path?.contains("forms") == true
}
webViewClient = object : IOWebViewClient(this@WebViewActivity) {
    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)

        val uri = Uri.parse(url)
        val alreadyResponded = url?.contains("/alreadyresponded") == true
        val responded = url?.contains("/formResponse") == true
        if (WebViewUtil.isGoogleFormUrl(uri) && (alreadyResponded || responded)) {
            isCompleted = true
            // 제출 후 뒤로가기시 바로 이전화면으로 보내기 위함.
            view?.clearHistory()
        }
    }
}

특별히 설명할 부분은 clearHistory 부분이다.

제출 완료 후에 뒤로가기를 누르면 이전 설문 응답 화면이 그대로 나오는데, 일반적으로 제출하면 바로 원래 앱 화면으로 돌아가기를 바라기 때문에 이전 History들을 모두 지워주는 것이 자연스럽다.

 

 

 

 

이 글이 도움이 되었다면? 공감 - !