Google 월렛에 탑승권 추가

Google 메시지를 RCS 및 Google 월렛과 함께 사용하면 원활한 체크인 절차를 설계할 수 있습니다. 사용자는 체크인을 완료하고 탑승권을 받아 메시지 앱에서 바로 Google 월렛에 추가할 수 있습니다. 월렛에 로그인하면 항공편 세부정보가 변경되면 자동으로 패스가 업데이트됩니다. 사용자는 휴대전화에서 바로 최신 탑승권에 빠르게 액세스할 수 있습니다.

이 문서에서는 Google 월렛으로의 탑승권을 구현하기 위한 기술적 단계를 설명합니다. 또한 RBM을 통한 원활하고 효율적인 체크인 환경을 위한 디자인 팁이 포함된 샘플 대화가 제공됩니다.

기술적 구현

Google 월렛 흐름에 탑승권을 구현하려면 Google Wallet API와 RBM API를 사용하세요.

기본 요건

Google Wallet API를 시작하려면 다음 필수 단계를 따르세요.

  1. Google 월렛용 패스를 만들고 배포할 수 있도록 월렛 발급기관 계정에 가입하세요.
  2. Google Cloud Platform (GCP) 프로젝트가 없는 경우 프로젝트를 만듭니다.
  3. Google Wallet API를 사용 설정합니다.
  4. Google Wallet API를 호출할 수 있도록 서비스 계정과 키를 만드세요.
  5. Google Pay 및 월렛 콘솔에서 서비스 계정을 승인합니다.
  6. 탑승권 템플릿을 사용하여 새 탑승 클래스를 만듭니다.

Google Wallet API

탑승권을 만들고 RBM의 Google 월렛에 추가 URL을 생성하려면 다음 단계를 따르세요.

  1. 필요한 인증 및 승인을 실행합니다.
  2. Passes 객체를 만듭니다.
  3. 서명된 JSON 웹 토큰 (JWT)을 가져옵니다. 인코딩된 JWT의 최대 길이는 2,048자입니다.
  4. JWT를 사용하여 Google 월렛에 추가 URL을 생성합니다.

RBM API

RBM에서 Google 월렛에 추가 추천을 보내려면 URL 열기 작업을 보냅니다. 메시지 페이로드에서 다음을 수행합니다.

  1. text에 'Google 월렛에 추가'를 입력합니다.
  2. url에 Google 월렛에 추가 URL을 입력합니다.

Google 월렛 아이콘이 추천 라벨에 자동으로 표시됩니다.

'Google 월렛에 추가' 추천의 Google 월렛 아이콘

대화 디자인

이 샘플은 고유한 체크인 과정을 사용하여 사용자에게 전체 체크인 과정을 안내합니다. 여기에서는 자연스러운 대화와 탭 한 번으로 추천, 리치 카드와 같은 리치 기능을 사용하여 사용자가 목표에 도달하는 데 도움을 주는 방법을 보여줍니다. 이 경우 목표는 (1) 항공편 경험을 맞춤설정하고, (2) 탑승권을 받고, (3) 공항에서 쉽게 액세스할 수 있도록 Google 월렛에 추가하는 것입니다.

다음은 대화의 개요입니다. 그 뒤에는 디자인 팁과 흐름의 단계별 분석이 나옵니다. 에이전트에 비슷한 디자인을 구현하려면 단계 아래의 코드 샘플을 참조하세요.

대화 다이어그램

디자인 조언

체크인 흐름을 설계할 때 다음 원칙에 유의하세요.

  • 첫 번째 메시지가 가장 중요합니다. 사용자가 대화할 이유가 있도록 대화의 목적을 간단히 설명합니다.
  • 각 메시지는 작은 정보 청크를 제공하고 사용자에게 응답하라는 메시지를 표시해야 합니다. 추천 답장추천 작업을 사용하면 다음 단계로 쉽게 넘어갈 수 있습니다.
  • 에이전트는 로봇이 아닌 반응형이어야 합니다. 브랜드의 어조를 반영하는 언어를 사용하세요. 이상적인 브랜드 담당자는 고객과 어떻게 채팅하나요?
  • 사람들은 특별하게 느끼고 싶어 합니다. 사용자의 항공편 기록을 토대로 좌석 또는 식사를 추천하여 체크인 환경을 맞춤설정할 수 있습니다.
  • 리치 카드캐러셀을 사용하면 대화가 더욱 역동적으로 이루어집니다. 이를 통해 사용자가 옵션을 선택하는 데 도움이 되는 이미지와 세부정보를 공유할 수 있습니다.
  • 좋은 대화는 잘 끝납니다. 탑승권을 보내기 전에 사용자의 체크인 세부정보를 확인합니다. 친근한 말투로 인간적인 느낌을 더하세요.

체크인 절차

  1. 상담사가 사용자에게 항공편 체크인이 열려 있다고 알립니다.

    체크인 세부정보 및 추천 답장이 포함된 인사말 메시지

    코드 샘플

    const suggestions = [
      {
        reply: {
          text: '⚡ Check in',
          postbackData: 'checkIn',
        },
      },
      {
        reply: {
          text: '⏰ Remind me later',
          postbackData: 'remindMe',
        },
      },
      {
        reply: {
          text: '✈️ View my flight details',
          postbackData: 'flightDetails',
        },
      },
      {
        reply: {
          text: '🔀 Change my flight',
          postbackData: 'flightChange',
        },
      },
    ];  
    
    const params = {
      messageText: 'Check-in for your flight',
      messageDescription: '👏 Happy morning, Jo! Check-in is now open for your flight from London to Mumbai on ' + getFlightTime() + ' at 2:00PM. What would you like to do? ',
      msisdn: phoneNumber,
      suggestions: suggestions,
      imageUrl: getImageUrl('fly.png'),
      height: 'MEDIUM',
    };  
    
    rbmApiHelper.sendRichCard(params);      
    

  2. 사용자가 체크인할 추천 답장을 탭합니다.

    체크인 추천을 탭했습니다.

  3. 상담사가 확인 절차에 관한 기대치를 설정합니다.

    메시지 상태: 좋습니다. 간단한 3단계만 거치면 됩니다. 온보딩을 위한 첫 번째 단계입니다.

    코드 샘플

    const params = {
      messageText: "OK, great. It's just 3 simple steps to check in. Here's the first step to get you onboard:",
      msisdn: msisdn,
    };  
    
    let self = this;
    
    rbmApiHelper.sendMessage(params, function (response, err) {
      self.sendPolicyImage(msisdn);
    });   
    

  4. 상담사가 사용자에게 안전 정책에 동의해 달라고 요청합니다.

    안전 정책에 대한 인포그래픽과 동의하거나 동의하지 않을 것을 제안하는 리치 카드입니다. 카드에 다음과 같은 텍스트가 표시되어 있습니다. Google에서 안전한 항공편을 보장하기 위해 안전 정책을 검토하고 동의해 주세요.

    코드 샘플

    const suggestions = [
      {
        reply: {
          text: 'Yes, I agree',
          postbackData: 'policy_agree',
        },
      },
      {
        reply: {
          text: "No, I don't agree",
          postbackData: 'policy_nack',
        },
      },
    ];  
    
    const params = {
      messageText: 'Baggage safety policy',
      messageDescription: 'To help us ensure a safe flight, please review our safety policy and let us know you agree',
      msisdn: msisdn,
      suggestions: suggestions,
      imageUrl: getImageUrl('policyImage.png'),
      height: 'MEDIUM',
      orientation: 'HORIZONTAL',
      thumbnailImageAlignment: 'LEFT',
    };  
    
    rbmApiHelper.sendRichCard(params);
    

  5. 사용자가 제안된 답변을 탭하여 동의합니다.

    동의 요청 탭함

  6. 상담사가 사용자에게 감사를 표하고 다음 단계를 소개합니다.

    메시지 내용: 감사합니다. 안전한 승객은 행복한 승객입니다. 다음 단계

    코드 샘플

    const params = {
      messageText: "Thank you - A safe passenger is a happy passenger! Here's the next step:",
      msisdn: msisdn,
    };
    
    let self = this;
    
    rbmApiHelper.sendMessage(params, function (response, err) {
      self.sendPlan(msisdn);
    });     
    

  7. 상담사가 사용자에게 좌석을 선택하라는 메시지를 표시합니다.

    좌석 지도 인포그래픽이 포함된 리치 카드입니다. 카드에 적힌 '편안한 휴식 시간'이라고 적혀 있습니다. 최근 항공편을 기준으로 일부 좌석을 추천했습니다. 원하는 좌석을 선택하거나 번호를 입력하여 원하는 좌석을 알려주세요. 카드 아래에는 몇 가지 좌석 옵션이 표시됩니다.

    코드 샘플

    const suggestions = [
      {
        reply: {
          text: 'View the seat map',
          postbackData: 'view_seat_map',
        },
      },
    ];
    
    const outerSuggestions = [
      {
        reply: {
          text: '17A',
          postbackData: 'seat_17A',
        },
      },
      {
        reply: {
          text: '17C',
          postbackData: 'seat_17C',
        },
      },
      {
        reply: {
          text: '18A',
          postbackData: 'seat_18A',
        },
      },
      {
        reply: {
          text: 'Show me more',
          postbackData: 'more',
        },
      },
    ];  
    
    const params = {
      messageText: 'Choose your seat',
      messageDescription: "It's time to sit back and get comfy! 💺 We've recommended some seats based on your last flight. Choose the one you want, or let us know your preferred seat by typing the number.",
      msisdn: msisdn,
      imageUrl: getImageUrl('seatMap.png'),
      height: 'TALL',
      orientation: 'VERTICAL',
      outerSuggestions: outerSuggestions
    };  
    
    rbmApiHelper.sendRichCard(params);
    

  8. 사용자가 선택한 좌석의 추천 답변을 탭합니다.

    18A번 좌석 추천이 탭됨

  9. 상담사가 사용자의 선택을 확인합니다.

    메시지 상태: 18A번입니다. 알겠습니다.

    코드 샘플

    this.seatmap[msisdn] = seat;  
    
    const params = {
      messageText: `Seat ${seat}, you got it`,
      msisdn: msisdn,
    };  
    
    let self = this;  
      rbmApiHelper.sendMessage(params, function(res) {
        self.sendFoodOptions(msisdn);
    }); 
    

  10. 상담사가 사용자에게 기내 식사를 선택하도록 요청합니다.

    메시지 상태: 이제 음식에 대해 알아보겠습니다. 기내식을 선주문할 수 있습니다. 채식 메뉴나 닭고기 메인 요리를 좋아하시나요?

    코드 샘플

    const params = {
      messageText: `Now let's talk food 😋 You can pre-order your in-flight meal. Would you be happy with a vegetarian entree or a chicken entree?`,
      msisdn: msisdn,
    };  
    
    let self = this;  
    
    rbmApiHelper.sendMessage(params, function(res) {
      self.sendFoodDetails(msisdn);
    });
    

  11. 식사 옵션이 표시됩니다.

    리치 카드 캐러셀에는 샐러드 이미지와 로스트 치킨 이미지가 포함된 카드가 두 개 표시됩니다. 두 카드 모두 재료 목록과 식사 선택 제안이 있습니다.

    코드 샘플

    const cardContents = [
      {
        title: 'Panzanella salad (v)',
        description: 'Ingredients: bread, lettuce, onions, tomatoes, olive oil',
        suggestions: [
          {
            reply: {
              text: 'Choose vegetarian',
              postbackData: 'veggie',
            },
          },
        ],
        media: {
          height: 'MEDIUM',
          contentInfo: {
            fileUrl: getImageUrl('salad.jpg'),
          },
        },
      },
      {
        title: 'Grilled chicken with greens',
        description: 'Ingredients: chicken, potatoes, peppers, olive oil',
        suggestions: [
          {
            reply: {
              text: 'Choose chicken',
              postbackData: 'chicken',
            },
          },
        ],
        media: {
          height: 'MEDIUM',
          contentInfo: {
            fileUrl: getImageUrl('chicken.png'),
          },
        },
      },
    ];  
    
    const params = {
      msisdn: msisdn,
      cardContents: cardContents,
    };  
    
    rbmApiHelper.sendCarouselCard(params);
    

  12. 사용자가 선택한 식사의 추천 답변을 탭합니다.

    채식주의자 선택 제안을 탭함

  13. 상담사가 사용자의 선택을 확인합니다.

    메시지 내용: 채식주의자입니다.

    코드 샘플

    const params = {
      messageText: `Vegetarian it is 💚`,
      msisdn: msisdn,
    };  
    
    let self = this;  
    
    rbmApiHelper.sendMessage(params, function (response, err) {
      self.sendAskConfirmation(msisdn);  
    });
    

  14. 상담사가 체크인 세부정보를 요약합니다.

    메시지 상태: 18A번과 채식주의자 음식을 선택하셨습니다. 선택한 내용을 확인하세요. 세부정보를 확인하거나, 식사를 변경하거나, 좌석을 변경하라는 메시지가 메시지 아래에 표시됩니다.

    코드 샘플

    let seat = this.seatmap[msisdn];  
    
    const suggestions = [
      {
        reply: {
          text: "Yes, I'm happy with that",
          postbackData: 'happy',
        },
      },
      {
        reply: {
          text: 'Change my seat',
          postbackData: 'change_seat',
        },
      },
      {
        reply: {
          text: 'Change my meal',
          postbackData: 'change_meal',
        },
      },
    ];
    
    const params = {
      messageText: "Here's what we've noted down: You've opted for seat " + seat + " and a vegetarian meal. Please confirm your choices.",
      msisdn: msisdn,
      suggestions: suggestions
    };  
    
    rbmApiHelper.sendMessage(params);  
    

  15. 사용자가 추천 답변을 탭하여 체크인 세부정보를 확인합니다.

    세부정보를 탭했는지 확인하는 제안

  16. 상담사가 체크인이 완료되었다고 알립니다.

    메시지 상태: 만세! 항공편 체크인이 완료되었습니다. 탑승권입니다. 곧 귀사를 주최하게 되어 기쁘게 생각합니다.

    코드 샘플

    const params = {
      messageText: "Hooray! You're now checked in for your flight ☑️ Here's your boarding pass. We're so happy to host you soon!",
      msisdn: msisdn,
    };  
    
    let self = this;  
    
    rbmApiHelper.sendMessage(params, function (response, err) {
      self.sendWalletPass(msisdn);       
    }); 
    

  17. 상담사가 사용자의 탑승권을 전송합니다.

    리치 카드에는 QR 코드 및 항공편 세부정보가 포함된 탑승권 이미지가 표시됩니다. 카드 텍스트: 최신 정보를 알려 드리겠습니다. 항공편 세부정보가 변경되면 알림이 전송됩니다. 카드에 Google 월렛에 추가하라는 제안이 표시됨

    코드 샘플

    this.walletHelper.createFlightPassUrl(this.seatmap[msisdn]).then((url) => {
      let suggestions = [
        {
          action: {
            text: 'Add to Google Wallet',
            postbackData: 'addToWallet',
            openUrlAction: {
              url: url
            },
          },
        },
      ];  
    
      const params = {
        messageText: 'HS123 LHR to BOM\nPassenger: Jo Flow',
        messageDescription: "We'll keep you up to date! You'll get a notification if your flight details change.",
        msisdn: msisdn,
        suggestions: suggestions,
        imageUrl: getImageUrl('boardingPass.png'),
        height: 'TALL',
        orientation: 'HORIZONTAL',
        thumbnailImageAlignment: 'LEFT',
      };  
    
      rbmApiHelper.sendRichCard(params);
    }); 
    

    가로 리치 카드에서 이미지는 항공사에서 제공하는 모든 기능을 갖춘 탑승권입니다. 이미지에 스캔 가능한 바코드를 포함하여 필요한 탑승 정보가 모두 표시되어야 합니다. 사용자는 이미지를 탭하여 Google의 메시지 앱에서 탑승권을 확인하고 스캔하기만 하면 됩니다.

    리치 카드에 Google 월렛에 추가 추천이 표시됩니다. 이 제안은 사용자가 월렛에 탑승권을 쉽게 추가할 수 있도록 Google 월렛 앱을 여는 URL 열기 작업을 트리거합니다. (앱이 사용자 기기에 없으면 앱을 설치하라는 메시지가 표시됩니다.) 패스가 Google 월렛에 추가되면 항공편 세부정보가 변경되면 항공편 알림상태 업데이트가 자동으로 전송됩니다.

    패스를 Google 월렛에 추가하지 않은 사용자도 최신 정보를 유지해야 합니다. 리치 카드에 표시되는 탑승 정보가 변경되면 사용자에게 메시지를 보냅니다.

  18. 사용자가 제안된 작업을 탭하여 Google 월렛에 패스를 추가합니다.

    Google 월렛 아이콘 및 Google 월렛에 추가하라는 제안

  19. Google 월렛 앱이 열립니다. 사용자가 버튼을 탭하여 패스를 월렛에 추가합니다.

    월렛 앱에 단순화된 탑승권과 추가 버튼이 표시됩니다.

  20. 사용자가 버튼을 탭하여 패스를 확인합니다.

    체크표시 위에 패스가 표시됩니다. Google 월렛에 보기 버튼이 표시됩니다.

  21. QR 코드가 있는 탑승권이 표시됩니다.

    모든 항공편 세부정보와 QR 코드가 포함된 탑승권