웹훅

작업을 더욱 유연하게 빌드할 수 있도록 로직을 위임할 수 있습니다. HTTPS 웹 서비스 (처리)로 이동합니다 작업은 요청할 수 있습니다 할 수 있는 작업의 몇 가지 예 fulfillment에는 다음이 포함됩니다.

  • 사용자가 제공한 정보를 기반으로 동적 프롬프트 생성
  • 외부 시스템에 주문하고 성공 확인
  • 백엔드 데이터로 슬롯의 유효성을 검사합니다.
그림 1. 호출 인텐트 및 장면은 웹훅이 필요합니다.

웹훅 트리거 및 핸들러

작업은 호출 인텐트 또는 장면 내에서 웹훅을 트리거할 수 있습니다. 처리 엔드포인트에 요청을 보냅니다 처리에 웹훅이 포함되어 있습니다. 요청의 JSON 페이로드를 처리하는 핸들러 웹훅을 트리거할 수 있습니다. 사용할 수 없습니다.

  • 호출 인텐트 일치 후
  • 장면의 진입 무대
  • 장면의 조건 단계에서 조건이 true로 평가된 후
  • 장면의 슬롯 채우기 단계
  • 장면의 입력 단계에서 인텐트 일치가 발생한 후

작업에서 웹훅을 트리거하면 Google 어시스턴트가 요청을 JSON 페이로드로 대체합니다. 이벤트를 처리하는 데 사용할 핸들러의 이름입니다. 처리 엔드포인트는 이벤트를 적절한 핸들러로 라우팅하여 로직을 실행하고 해당하는 JSON 페이로드가 포함된 응답을 반환합니다.

페이로드

다음 스니펫은 작업에서 보내는 요청 예시를 보여줍니다. fulfillment와 응답이 반송되는 응답이 포함됩니다. 자세한 내용은 자세한 내용은 참조 문서를 확인할 수 있습니다

요청 예

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "example_session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

응답 예

{
  "session": {
    "id": "example_session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Hello World.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  }
}

런타임 상호작용

다음 섹션에서는 웹훅 핸들러를 만드세요

메시지 보내기

간단한 텍스트, 서식 있는 텍스트, 카드는 물론 완성된 형태의 프롬프트를 만들 수 있습니다. Interactive Canvas를 통해 웹 앱에서 지원하는 HTML 프롬프트 프롬프트 문서에는 웹훅 이벤트를 처리할 때 프롬프트를 만드는 방법에 대한 자세한 내용을 확인하세요. 다음 스니펫은 카드 프롬프트를 보여줍니다.

Node.js

app.handle('rich_response', conv => {
  conv.add('This is a card rich response.');
  conv.add(new Card({
    title: 'Card Title',
    subtitle: 'Card Subtitle',
    text: 'Card Content',
    image: new Image({
      url: 'https://developers.google.com/assistant/assistant_96.png',
      alt: 'Google Assistant logo'
    })
  }));
});

응답 JSON

{
  "session": {
    "id": "example_session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "content": {
      "card": {
        "title": "Card Title",
        "subtitle": "Card Subtitle",
        "text": "Card Content",
        "image": {
          "alt": "Google Assistant logo",
          "height": 0,
          "url": "https://developers.google.com/assistant/assistant_96.png",
          "width": 0
        }
      }
    },
    "firstSimple": {
      "speech": "This is a card rich response.",
      "text": ""
    }
  }
}

인텐트 매개변수 읽기

어시스턴트 런타임은 인텐트와 일치할 때 정의된 모든 항목을 추출합니다. 매개변수입니다. 원래 속성은 사용자가 입력으로 제공한 속성이며 해결됨 속성은 NLU가 유형에 따라 입력을 확인한 속성입니다. 지정할 수도 있습니다

Node.js

conv.intent.params['param_name'].original
conv.intent.params['param_name'].resolved

요청 JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "intent_name",
    "params": {
      "slot_name": {
        "original": "1",
        "resolved": 1
      }
    },
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {},
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

사용자 언어 읽기

이 값은 Google 어시스턴트의 사용자 언어 설정에 해당합니다.

Node.js

conv.user.locale

JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

저장소 읽기 및 쓰기

다음 작업을 수행하는 방법에 대한 자세한 내용은 스토리지 문서를 참조하세요. 다양한 스토리지 기능을 사용할 수 있습니다

Node.js

//read
conv.session.params.key
conv.user.params.key
conv.home.params.key

// write
conv.session.params.key = value
conv.user.params.key = value
conv.home.params.key = value 

요청 JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {
      "key": "value"
    },
    "typeOverrides": [],
    "languageCode": ""
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED",
      "key": "value"
    }
  },
  "home": {
    "params": {
      "key": "value"
    }
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

응답 JSON

{
  "session": {
    "id": "session_id",
    "params": {
      "key": "value"
    }
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "Hello world.",
      "text": ""
    }
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED",
      "key": "value"
    }
  },
  "home": {
    "params": {
      "key": "value"
    }
  }
}

기기 기능 확인

기기의 기능을 확인하여 다양한 환경을 제공하거나 대화 흐름에 영향을 줄 수 있습니다.

Node.js

const supportsRichResponse = conv.device.capabilities.includes("RICH_RESPONSE");
const supportsLongFormAudio = conv.device.capabilities.includes("LONG_FORM_AUDIO");
const supportsSpeech = conv.device.capabilities.includes("SPEECH");
const supportsInteractiveCanvas = conv.device.capabilities.includes("INTERACTIVE_CANVAS");

요청 JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "actions.intent.MAIN",
    "params": {},
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "UNSPECIFIED",
    "slots": {}
  },
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": [],
    "languageCode": ""
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO",
      "INTERACTIVE_CANVAS"
    ]
  }
}

노출 영역 기능의 전체 목록은 Capability를 참고하세요. 참조

런타임 유형 재정의

런타임 유형을 사용하면 런타임에 유형 사양을 수정할 수 있습니다. 이 다른 소스에서 데이터를 로드하여 유형의 유효한 값을 채우는 기능을 제공합니다. 대상 예를 들어 런타임 유형 재정의를 사용하여 설문조사에 동적 옵션을 추가할 수 있습니다. 일일 항목을 메뉴에 추가할 수 있습니다.

런타임 유형을 사용하려면 작업으로부터 핸들러를 만들어야 합니다. 여기에서 session.typeOverrides 매개변수가 포함됩니다. 사용 가능 모드에는 기존 유형 항목을 보존하는 TYPE_MERGE 또는 TYPE_REPLACE가 포함됩니다. 기존 항목을 재정의로 대체합니다.

Node.js

conv.session.typeOverrides = [{
    name: type_name,
    mode: 'TYPE_REPLACE',
    synonym: {
      entries: [
        {
          name: 'ITEM_1',
          synonyms: ['Item 1', 'First item']
        },
        {
          name: 'ITEM_2',
          synonyms: ['Item 2', 'Second item']
       },
       {
          name: 'ITEM_3',
          synonyms: ['Item 3', 'Third item']
        },
        {
          name: 'ITEM_4',
          synonyms: ['Item 4', 'Fourth item']
        },
    ]
  }
}];

응답 JSON

{
  "session": {
    "id": "session_id",
    "params": {},
    "typeOverrides": [
      {
        "name": "type_name",
        "synonym": {
          "entries": [
            {
              "name": "ITEM_1",
              "synonyms": [
                "Item 1",
                "First item"
              ]
            },
            {
              "name": "ITEM_2",
              "synonyms": [
                "Item 2",
                "Second item"
              ]
            },
            {
              "name": "ITEM_3",
              "synonyms": [
                "Item 3",
                "Third item"
              ]
            },
            {
              "name": "ITEM_4",
              "synonyms": [
                "Item 4",
                "Fourth item"
              ]
            }
          ]
        },
        "typeOverrideMode": "TYPE_REPLACE"
      }
    ]
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": "This is an example prompt."
    }
  }
}

음성 바이어스 제공

음성 바이어스를 통해 NLU에 힌트를 지정하여 인텐트 일치를 개선할 수 있습니다. 나 최대 1,000개의 항목을 지정할 수 있습니다

Node.js

conv.expected.speech = ['value_1', 'value_2']
conv.expected.language = 'locale_string'

응답 JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": "This is an example prompt."
    }
  },
  "expected": {
    "speech": "['value_1', 'value_2']",
    "language": "locale_string"
  }
}

전환 장면

작업 프로젝트에서 정적 전환을 정의하는 것 외에도 런타임에 장면 전환이 발생하도록 합니다.

Node.js

app.handle('transition_to_hidden_scene', conv => {
  // Dynamic transition
  conv.scene.next.name = "HiddenScene";
});

응답 JSON

{
  "session": {
    "id": "session_id",
    "params": {}
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {},
    "next": {
      "name": "HiddenScene"
    }
  }
}

장면 슬롯 읽기

슬롯 채우기 중에 처리를 사용하여 슬롯을 검증하거나 슬롯 채우기 상태 (SlotFillingStatus)

Node.js

conv.scene.slotFillingStatus  // FINAL means all slots are filled
conv.scene.slots  // Object that contains all the slots
conv.scene.slots['slot_name'].<property_name> // Accessing a specific slot's properties

예를 들어 응답에서 시간대를 추출한다고 가정해 보겠습니다. 포함 이 예에서 슬롯 이름은 datetime1입니다. 시간대를 구하려면 사용:

conv.scene.slots['datetime1'].value.time_zone.id

요청 JSON

{
  "handler": {
    "name": "handler_name"
  },
  "intent": {
    "name": "",
    "params": {
      "slot_name": {
        "original": "1",
        "resolved": 1
      }
    },
    "query": ""
  },
  "scene": {
    "name": "SceneName",
    "slotFillingStatus": "FINAL",
    "slots": {
      "slot_name": {
        "mode": "REQUIRED",
        "status": "SLOT_UNSPECIFIED",
        "updated": true,
        "value": 1
      }
    },
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  },
  "session": {
    "id": "session_id",
    "params": {
      "slot_name": 1
    },
    "typeOverrides": []
  },
  "user": {
    "locale": "en-US",
    "params": {
      "verificationStatus": "VERIFIED"
    }
  },
  "home": {
    "params": {}
  },
  "device": {
    "capabilities": [
      "SPEECH",
      "RICH_RESPONSE",
      "LONG_FORM_AUDIO"
    ]
  }
}

장면 슬롯 무효화

슬롯을 무효화하고 사용자가 새 값을 제공하도록 할 수 있습니다.

Node.js

conv.scene.slots['slot_name'].status = 'INVALID'

응답 JSON

{
  "session": {
    "id": "session_id",
    "params": {
      "slot_name": 1
    }
  },
  "prompt": {
    "override": false,
    "firstSimple": {
      "speech": "This is an example prompt.",
      "text": ""
    }
  },
  "scene": {
    "name": "SceneName",
    "slots": {
      "slot_name": {
        "mode": "REQUIRED",
        "status": "INVALID",
        "updated": true,
        "value": 1
      }
    },
    "next": {
      "name": "actions.scene.END_CONVERSATION"
    }
  }
}

개발 옵션

<ph type="x-smartling-placeholder">
</ph> <ph type="x-smartling-placeholder"></ph>

Actions Builder는 Cloud Functions 편집기라는 인라인 편집기를 제공합니다. Google Cloud 콘솔에서 바로 Firebase용 Cloud 함수를 살펴보겠습니다 선택한 호스팅에 처리를 빌드하고 배포할 수도 있습니다. HTTPS 처리 엔드포인트를 웹훅 핸들러로 등록합니다.

인라인 편집기

Cloud Functions 편집기로 개발하려면 다음 안내를 따르세요.

  1. sdk/webhooks/ActionsOnGoogleFulfillment.yaml 파일을 만듭니다. 작업의 핸들러와 사용할 인라인 Cloud 함수를 정의합니다. 살펴보겠습니다
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc
    inlineCloudFunction:
      executeFunction: ActionsOnGoogleFulfillment
        
  2. sdk/webhooks/ActionsOnGoogleFulfillment 폴더를 만듭니다. 그리고 핸들러를 구현하는 index.js 파일을 추가합니다. npm을 정의하는 package.json 파일 코드 요구사항에 따라 다릅니다
    // index.js
    const {conversation} = require('@assistant/conversation');
    const functions = require('firebase-functions');
    
    const app = conversation();
    
    app.handle('questionOnEnterFunc', conv => {
      conv.add('questionOnEnterFunc triggered on webhook');
    });
    
    app.handle('fruitSlotValidationFunc', conv => {
      conv.add('fruitSlotValidationFunc triggered on webhook');
    });
    
    exports.ActionsOnGoogleFulfillment = functions.https.onRequest(app);
        
    // package.json
    {
      "name": "ActionsOnGoogleFulfillment",
      "version": "0.1.0",
      "description": "Actions on Google fulfillment",
      "main": "index.js",
      "dependencies": {
        "@assistant/conversation": "^3.0.0",
        "firebase-admin": "^5.4.3",
        "firebase-functions": "^0.7.1"
      }
    }
        

외부 HTTPS 엔드포인트

이 섹션에서는 Firebase용 Cloud Functions를 fulfillment 서비스를 제공합니다. 하지만 Cloud Shell에서 처리를 원하는 호스팅 서비스로 처리할 수 있습니다.

환경 설정

Cloud Functions를 사용하는 경우 다음과 같은 프로젝트 구조를 사용하는 것이 좋습니다. 처리 서비스로서의 Firebase:

ProjectFolder        - Root folder for the project
  sdk                - Actions project configuration files
  functions          - Cloud functions for Firebase files

환경을 설정하려면 다음 단계를 수행합니다.

  1. Node.js를 다운로드하고 설치합니다.
  2. Firebase CLI를 설정하고 초기화합니다. 다음 명령어가 EACCES 오류가 발생하면 npm 권한을 변경해야 할 수 있습니다.

    npm install -g firebase-tools
    
  3. Google 계정으로 Firebase 도구를 인증합니다.

    firebase login
    
  4. 작업 프로젝트를 저장한 프로젝트 디렉터리를 시작합니다. 설정할 Firebase CLI 기능을 선택하라는 메시지가 표시됩니다. 확인할 수 있습니다 Functions 및 기타 기능을 선택하세요. 사용한 다음 Enter 키를 눌러 확인하고 계속 진행합니다.

    $ cd <ACTIONS_PROJECT_DIRECTORY>
    $ firebase init
    
  5. 다음을 사용하여 Firebase 도구를 작업 프로젝트와 연결합니다. 화살표 키를 사용하여 프로젝트 목록을 탐색합니다.

  6. 프로젝트를 선택하면 Firebase 도구가 설정하고 싶은 언어를 묻습니다. 화살표 키를 사용하여 선택 Enter 키를 눌러 계속 진행합니다.

    === Functions Setup
    A functions directory will be created in your project with a Node.js
    package pre-configured. Functions can be deployed with firebase deploy.
    
    ? What language would you like to use to write Cloud Functions? (Use arrow keys)
    > JavaScript
    TypeScript
    
  7. ESLint를 사용하여 Y 또는 N을 입력하여 잠재적 버그를 발견하고 스타일을 적용할지 선택합니다.

    ? Do you want to use ESLint to catch probable bugs and enforce style? (Y/n)
  8. 프롬프트에 Y를 입력하여 프로젝트 종속 항목을 가져옵니다.

    ? Do you want to install dependencies with npm now? (Y/n)

    설정이 완료되면 다음과 비슷한 출력이 표시됩니다.

    ✔  Firebase initialization complete!
    
  9. @assistant/conversation 종속 항목을 설치합니다.

    $ cd <ACTIONS_PROJECT_DIRECTORY>/functions
    $ npm install @assistant/conversation --save
    
  10. fulfillment 종속 항목을 가져오고 fulfillment 함수를 배포합니다.

    $ npm install
    $ firebase deploy --only functions
    

    배포하는 데 몇 분 정도 걸립니다. 완료되면 다음과 비슷한 출력이 표시됩니다. 다음과 같이 변경합니다. Dialogflow에 입력할 함수 URL이 필요합니다.

    ✔  Deploy complete!
    Project Console: https://console.firebase.google.com/project/<PROJECT_ID>/overview Function URL (<FUNCTION_NAME>): https://us-central1-<PROJECT_ID>.cloudfunctions.net/<FUNCTION_NAME>
  11. 다음 섹션에서 사용할 처리 URL을 복사합니다.

웹훅 핸들러 등록

  1. sdk/webhooks/ActionsOnGoogleFulfillment.yaml 파일을 만들고 작업의 핸들러와 웹훅 요청의 URL이 있습니다.
    httpsEndpoint:
      baseUrl: https://my.web.hook/ActionsOnGoogleFulfillment
      endpointApiVersion: 2
    handlers:
    - name: questionOnEnterFunc
    - name: fruitSlotValidationFunc