서버 없는 WhatsApp 채팅 로봇 개발

This article is part of . You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September.

Find out more about how Microsoft Azure enables your Serverless functions at https://docs.microsoft.com/azure/azure-functions/.


채팅 로봇은 인공지능 소프트웨어로 자연 언어로 사용자와 상호작용을 할 수 있다.그들은 사용자의 메시지에서 키워드를 추출하여 사용자의 의도를 측정하고 그들의 요청에 적당한 응답을 제공할 수 있다.그것들은 현재 매우 중요하다. 왜냐하면 그들은 중복되고 시간이 소모되는 임무에 효과적으로 사용되기 때문에 회사가 다른 활동에 전념하고 자원(특히 인적자원)을 최적화할 수 있기 때문이다.
마이크로소프트는 로봇을 쉽게 개발하고 만들 수 있는 두 가지 핵심 기술LUISBot Framework을 제공했다.만약 인공지능 전문가가 아니라면 대화 로봇을 개발하고 배치하여 사용자와 상호작용하고 그들의 수요를 처리할 수 있다.Azure Bot Service를 등식에 추가하면 클라우드에 연결된 로봇이 있습니다. 예를 들어 스카이프, 마이크로소프트 팀, 페이스북 메신저, 심지어 웹 채팅 채널을 통해 당신의 사이트에 삽입할 수 있습니다. 아주 적은 설정 절차만 있으면 됩니다.
하지만 Azure Bot 서비스에는 현재 채널이 없습니다.WhatsAppthe most popular messenger app은 2019년 7월까지 월용 호수가 16억으로 현저한 예이다.우리의 고객은 이messenger 응용 프로그램을 통해 우리의 응용 프로그램과 통신하기를 희망합니다.
그렇다면, 우리는 어떻게 이 문제를 해결합니까?Azure의 구조 기능!우리는 웹 훅을 통해 Whats App 번호에 연결되는 서버 코드가 없는 것을 만들어서 일을 간소화할 수 있다.이것은 사용자가 이 번호로 메시지를 보낼 때마다 Azure 기능을 터치한다는 것을 의미한다.우리는 이를 자연 언어 처리의 루이스 모형에 연결시켜 회답에 지능을 주입할 수 있다.간단히 말하면, 우리는 세 가지 기술을 사용할 것이다.

  • LUIS(언어 이해 지능형 서비스)
  • Azure 기능

  • Twilio API(WhatsApp 액세스용)
  • 시작합시다!

    섹션 1: 루이스


    LUIS는 언어 이해 지능 서비스를 대표합니다.이것은 마이크로소프트 인공지능 플랫폼의 일부분으로 우리가 사용자의 정보에서 사용자의 의도와 관건적인 요소를 식별할 수 있도록 한다.스마트 언어 처리 모델을 만들기 위해서는 이전에 예시(언어)를 통해 훈련해야 한다
    1단계.새로 만들기LUIS application.

    단계 2.프로젝트에geographyV2 미리 만들어진 실체를 추가합니다.엔티티는 식별될 텍스트의 일부(예: 도시)를 나타냅니다.

    3단계.새 의도 만들기: GetCityWeather의향은 사용자의 수요를 나타낸다. 예를 들어 호텔 방을 예약하거나 제품을 찾거나 특정 도시의 날씨 조건을 요청한다.

    4단계.이 목적을 위해 최소 5개의 예시어를 추가합니다.도시는 자동으로 지오그래피 V2 실체로 검출됩니다.이 모델은 사용자가 특정 의도에 대해 말할 수 있는 예시 문장을 제공함으로써 더욱 스마트해진다.

    단계 5.Train 버튼을 클릭하여 LUIS 모델을 생성합니다.프로세스가 완료되면 새 요청으로 프로세스가 작동하는지 테스트합니다.

    단계 6.모델을 게시합니다.생산 슬롯을 선택하고 Azure 리소스로 이동합니다.예시 검색 상자의 URL을 복사합니다. 왜냐하면 우리는 잠시 후에 세 번째 부분에서 그것을 사용하여 Azure 함수를 조회하고 요청할 것입니다.

    섹션 2: OpenWeatherMap


    OpenWeatherMap는 우리가 특정 도시의 날씨 정보를 얻을 수 있는 서비스이다.
    1단계.서비스를 등록합니다.

    단계 2.API를 클릭하고 현재 날씨 데이터 API에 가입합니다.

    3단계.유휴 레이어 선택 및 API 키 가져오기

    4단계.API 키를 복사하면 다음 섹션에서 사용할 수 있습니다.

    섹션 3: Azure 기능


    Azure Functions는 서버 계산이 없는 서비스로 스크립트나 코드 세션을 실행하거나 이벤트에 응답할 수 있으며 인프라를 현저하게 설정하거나 관리할 필요가 없습니다.
    1단계.Azure 포털에서 새 기능 응용 프로그램을 만듭니다.그것의 이름은 유일하기 때문에 서버lesschatbot는 당신에게 적용되지 않습니다. 다른 것을 사용하십시오:-)

    단계 2.리소스를 만든 후 receive message라는 새 HTTP 트리거를 추가합니다.그런 다음 를 클릭하여 파일을 보고 함수를 추가합니다.프로젝트 파일

    3단계.이 파일은 Nuget 패키지를 프로젝트에 포함하는 데 사용됩니다.코드가 나중에 Whats App 번호와 상호작용할 수 있도록 Twilio 확장을 추가하고 있습니다.
    <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <TargetFramework>netstandard2.0</TargetFramework>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Twilio" Version="3.0.0" />
      </ItemGroup>
    </Project>
    
    4단계.다음은 실행 코드가 있습니다.csx, 이것은 Azure 함수의 주요 부분이다.이 예에서는 첫 번째 섹션 (6 단계) 의 URL과 두 번째 섹션 (4 단계) 의 API 키를 모두 사용하기 때문에 코드에서 대체합니다.
    코드의 첫 번째 부분에서, 우리는 LUIS와 OpenWeatherMap JSON이 응답하는 서비스를 호출한 후에 그것들을 반서열화하는 데 필요한 몇 가지 종류를 포함하고 있다.그리고 Run 방법의 코드 해석은 Whats App 번호로 보내는 메시지를 통해 생성된 유효 부하입니다.텍스트 부분을 추출합니다. 우리는 evaluate Message 방법을 사용하여 텍스트를 LUIS가 발표한 모델로 전송합니다. 이 모델은 메시지를 처리하고 도시 부분을 추출합니다.성공하면 특정 도시의 날씨를 얻기 위해 일기도를 열어 달라고 요청합니다.마지막으로 이 정보를 응답으로 사용자에게 보냅니다.
    #r "System.Runtime"
    #r "Newtonsoft.Json"
    
    using System.Net;
    using System.Text; 
    using System.Linq;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using Twilio.TwiML; 
    
    // LUIS classes
    public class LuisModel
    {
        public string query { get; set; }
        public TopScoringIntent topScoringIntent { get; set; }
        public List<Intent> intents { get; set; }
        public List<Entity> entities { get; set; }
    }
    
    public class TopScoringIntent
    {
        public string intent { get; set; }
        public double score { get; set; }
    }
    
    public class Intent
    {
        public string intent { get; set; }
        public double score { get; set; }
    }
    
    public class Entity
    {
        public string entity { get; set; }
        public string type { get; set; }
        public int startIndex { get; set; }
        public int endIndex { get; set; }
    }
    
    // OpenWeatherMap classes
    public class WeatherModel
    {
        public Coord coord { get; set; }
        public List<Weather> weather { get; set; }
        public string @base { get; set; }
        public Main main { get; set; }
        public int visibility { get; set; }
        public Wind wind { get; set; }
        public Clouds clouds { get; set; }
        public int dt { get; set; }
        public Sys sys { get; set; }
        public int id { get; set; }
        public string name { get; set; }
        public int cod { get; set; }
    }
    
    public class Weather
    {
        public int id { get; set; }
        public string main { get; set; }
        public string description { get; set; }
        public string icon { get; set; }
    }
    
    public class Coord
    {
        public double lon { get; set; }
        public double lat { get; set; }
    }
    
    public class Main
    {
        public double temp { get; set; }
        public double pressure { get; set; }
        public double humidity { get; set; }
        public double temp_min { get; set; }
        public double temp_max { get; set; }
    }
    
    public class Wind
    {
        public double speed { get; set; }
    }
    
    public class Clouds
    {
        public double all { get; set; }
    }
    
    public class Sys
    {
        public int type { get; set; }
        public int id { get; set; }
        public double message { get; set; }
        public string country { get; set; }
        public long sunrise { get; set; }
        public long sunset { get; set; }
    }
    
    // Main code
    public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
    {
        var data = await req.Content.ReadAsStringAsync();
    
        var formValues = data.Split('&') 
            .Select(value => value.Split('='))
            .ToDictionary(pair => Uri.UnescapeDataString(pair[0]).Replace("+", " "), 
                          pair => Uri.UnescapeDataString(pair[1]).Replace("+", " "));
    
        var text = formValues["Body"].ToString();
        var message = await evaluateMessage(text);
        var response = new MessagingResponse().Message(message);
    
        var twiml = response.ToString();
        twiml = twiml.Replace("utf-16", "utf-8");
    
        return new HttpResponseMessage
        { 
            Content = new StringContent(twiml, Encoding.UTF8, "application/xml")
        };
    }
    
    private static readonly HttpClient httpClient = new HttpClient();
    
    private static async Task<string> evaluateMessage(string text)
    {
        try
        {
            var luisURL = "Your-LUIS-URL-From-Step6-Part1";
            var luisResult = await httpClient.GetStringAsync($"{luisURL}{text});
            var luisModel = JsonConvert.DeserializeObject<LuisModel>(luisResult);
    
            if (luisModel.topScoringIntent.intent == "GetCityWeather")
            {
                var entity = luisModel.entities.FirstOrDefault();
    
                if (entity != null)
                {
                    if (entity.type == "builtin.geographyV2.city")
                    {
                        var city = entity.entity;
                        var apiKey = "Your-OpenWeatherMapKey-From-Step4-Part2";
    
                        var weatherURL = $"http://api.openweathermap.org/data/2.5/weather?appid={apiKey}&q={city}";
    
                        var weatherResult = await httpClient.GetStringAsync(weatherURL);
                        var weatherModel = JsonConvert.DeserializeObject<WeatherModel>(weatherResult);
                        weatherModel.main.temp -= 273.15;
    
                        var weather = $"{weatherModel.weather.First().main} ({weatherModel.main.temp.ToString("N2")} °C)";
                        return $"Weather of {city} is: {weather}";
                    }
                }
            }
            else
                return "Sorry, I could not understand you!";
        }
        catch(Exception ex)
        {
    
        }
    
        return "Sorry, there was an error!";
    }
    
    
    단계 5.함수 URL을 복사합니다. 마지막 부분에서 사용할 것입니다.

    마지막 부분: 트와일리오


    WhatsApp 번호와 통신하기 위해 Twilio API를 사용할 수 있습니다.
    1단계.생성free Twilio account

    단계 2.액세스Programmable SMS Dashboard 후 WhatsApp Beta를 선택하고 Get started 를 클릭합니다.

    3단계.WhatsApp의 Twilio 샌드박스를 활성화합니다.

    4단계.특정 WhatsApp 메시지를 장치에서 지정된 번호로 전송하여 테스트 샌드박스 설정


    단계 5.대화를 추가한 후 샌드박스를 다시 눌러 설정에 접근합니다.메시지를 받았을 때 의 URL을 이전 단계 5의 Azure 함수 URL로 바꿉니다.

    단계 6.그렇습니다!우리 일을 시험해 봅시다!

    성공예!
    여러 가지 기술이 관련되어 있기 때문에 모든 내용을 설정하는 데 시간이 필요할 것이다.그러나 너는 지금 여러 가지 가능성을 상상할 수 있다.당신이 알려준 사용자가 Whats App을 통해 당신의 응용 프로그램과 상호작용할 수 있다면 그들은 어떤 느낌을 갖게 될까요?아니면 그들은 문제를 특정한 번호로 보낼 수 있는데, 이 번호는 모든 문제를 처리할 것입니까?당신은 LUIS를 대체할 수 있습니다. 예를 들어 QnA Maker 사용자의 문제를 처리할 수 있습니다.예를 들어 이미지를 보내고 인지 서비스를 통해 분석할 수도 있다!
    하늘은 한계!:-)
    물론 Azure의 기능으로 인해 모든 것이 서버 없이 관리됩니다.
    시간 고마워요. 이 글이 도움이 됐으면 좋겠어요.Azure, Xamarin, 인공지능 등에 대한 더 많은 정보를 알고 싶으면 저blog와 저를 방문해 주십시오. 저는 보통 그곳에서 제 지식과 경험을 공유합니다.
    즐거운 인코딩!
    루이스
    PS: 저는 또 [Azure 창도자()의 제안에 감사드립니다! 매일 지역 사회와 전문가로부터 새로운 것을 배우는 것은 정말 대단합니다.
    본 출판물에 사용된 참고 문헌:
    Twilio

    좋은 웹페이지 즐겨찾기