Рубрики
Без рубрики

Получение страны и названия вашего пользователя в боте WhatsApp, используя FastApi и Faunadb

Привет, вы все! Да, я знаю, название это немного странно: Я должен был задокументировать свой проект, Дурин … Tagged с Python, Twiliohackathon, WebDev, ShowDev.

Привет, вы все! Да, я знаю, название это немного странно: Я должен был задокументировать свой проект во время Twilio Hackathon; Но, увы, у меня не было времени, чтобы сделать это. Итак, я решил сделать своего рода Post Mortem описывая роль, которая заняла у меня самое длинное, чтобы развить. Помимо этого, празднование моего второй Первый пост на Dev Я хотел заняться этим с другим углом.

Вместо того, чтобы делать учебник по книге, который заставил бы меня выглядеть очень умно, я хочу пройти через свой мыслительный процесс и задокументировать все Gotchas на этом пути; сохраняя это как можно более удобным для начинающих. Итак, начнем!

Что мы собираемся построить?

Мы собираемся построить виртуальный бот, используя Twilio Autopilot, в конце концов, этот бот будет работать через канал WhatsApp, но Autopilot позволяет вам подключаться к нескольким другим каналам, не изменяя код вашего бота. Этот причудливый бот спросит пользователя на его имя и сохранит его в базе данных вместе с номером телефона и стране пользователя. Вариант использования для этого? Ну, может быть, вы создаете виртуального помощника или просто хотите, чтобы бот был вежлив и приветствовал пользователя через их имя; возможности безграничны!

Стек

Вы, наверное, уже догадались, строительные блоки, которые нам нужны: во -первых, нам нужно сохранить данные; Итак, нам нужна база данных. Кроме того, нам нужно что -то, чтобы взаимодействовать с этой базой данных и сделать некоторую обработку, например, выяснить страну пользователя. Для первого я использовал FAUNADB: мульти-облачный децентрализованный сервис базы данных и, для более позднего, фреймворк Fastapi: фреймворк ASGI, созданная для современного питона.

Чего ждать?

подождите минуту, alessandro «Я слышу, как ты говоришь» Это много изысканных технических мамбо-джумбо, которые у вас там есть, не поэтапно разработать ? » Конечно, давайте посмотрим, что это за технологии и почему я их выбираю.

FAUNADB

Фауна Это база данных NOSQL, которая « построена для Jamstack «Эта последняя часть означает, что к ней предназначено доступ непосредственно из приложений передних концов, и из-за этого она дает возможность устанавливать разрешения очень гранулированным образом; так что вы можете с точностью управлять тем, к чему пользователи могут получить доступ к каким данным.

Часть noSQL означает (как вы уже догадались), что она не использует язык запросов схемы для получения запросов данных; Но это имя может иметь немного преуменьшения: это также означает, что это не делает предположений о форме ваших данных (держите это); Так что это означает, что внутри коллекции данных (например, пользователей) мы можем найти несоответствия в записях; Например: может быть, у пользовательской записи есть поле фамилии, а у другого пользователя нет.

Децентрализованная часть означает, что ваша база данных, которую она воспроизводится в нескольких случаях, это причудливый способ сказать, что есть куча копий вашей базы данных, разбросанных на нескольких различных серверах. Почему это хорошо? Потому что это предлагает Избыточность данных ; Конечно, может быть, вы слышали, что избыточность данных это корень всего зла, и их нужно искоренить с лица земли, но это зависит от контекста. В этом случае это хорошо, потому что это означает, что, если один из ваших серверов терпит неудачу, другие реплики существуют, чтобы гарантировать, что ваш сервис не прерывает и, что более важно, вы не теряете никаких данных; Это также означает, что данные будут сервером из реплики географически шкафу для пользователя, что приведет к более быстрому отклику. Эта репликация, которой труднее достичь, когда вам нужно настроить ее самостоятельно, но фауна отвлекает все эти хлопоты для нас.

Почему я выбираю это

Ну, все это объяснение звучит хорошо и хорошо, но причины, по которым я выбрал его, гораздо менее романтичны:

1) Стоимость, как и в деньгах: как разработчики, когда мы приступаем к побочному проекту, который необходимо размещать в прямом эфире, мы стараемся максимально минимизировать затраты. И хостинг базы данных – одна из тех вещей, которые могут быть дорогостоящими, особенно если вы не уделяете особого внимания модели ценообразования: вы можете получить счет, который выше, чем вы ожидали. У Фауны есть отличный бесплатный план, которого более чем достаточно. 2) природа схемы: как вы заметили, схема данных это довольно просто (имя, номер телефона и страна); Таким образом, раскручивая целую реляционную базу данных с SQLALCHEMY, миграциями, и это было немного чрезмерным. 3) Яичный любопытство: будучи базой данных, созданной для сервера, мне было любопытно посмотреть, сможет ли фауна адаптироваться к более традиционному применению, и, поскольку у них есть драйвер Python, который не был справедливым (предупреждение о спойлере: это так, вроде как).

FASTAPI

Fastaapi – это асинхронная структура стандартного интерфейса шлюза (ASGI), созданная для современного питона. Он построен на двух великих проектах: Starlette (еще один ASGI Framework) и Pydantic (библиотека проверки с нулевыми зависимостями). Итак, что в любом случае ASGI? Ну, это естественная эволюция интерфейса шлюза веб -сервера (WSGI).

Видите ли, если вы работали с рамкой WSGI (например, Flask или Django), вы знаете, что у них есть встроенные серверы; Таким образом, вы можете просто протестировать свое приложение в режиме реального времени при разработке, обычно с хорошими встроенными журналами и встроенными живыми перезагрузками. Дело в том, что, когда проект развертывается, Dev Server не будет его сокращать: вам понадобится настоящий сервер, такой как HTTP Webserver Apache, Nginx или IIS. Но подробно, что эти серверы обычно написаны в C/C ++, и они обрабатывают запросы через сокеты и все эти низкоуровневые вещи, они не говорят на Python! Таким образом, вам нужен «клей», чтобы серверы могли бы назвать ваше приложение Python, то есть WSGI.

Проблема с WSGI заключается в том, что она синхронна: она не может воспользоваться асинхронным программированием, таким образом, оно часто «медленнее», чем чистые асинхронные приложения, подобные тем, которые написаны с явными рамками или языком программирования GO.

Для этого был создан ASGI: он приносит новый интерфейс, который поддерживает асинхронный код на стороне сервера с помощью синтаксиса Python Async/Await, а также приносит новые функции, такие как поддержка HTTP/2 и веб-питания.

Я не буду погружаться в более подробную информацию об этом, это будет пост сам по себе. Но вы можете найти много материала на Интернет или здесь в Девчонка

Почему я выбираю это

1) Из -за Python! 2) Я некоторое время следил за Фастпи и просто искал оправдание, чтобы использовать его

Да, пара довольно объективных хорошо изученных причин прямо здесь; большое тебе спасибо.

Итак, давайте перейдем к дизайну бота. Во -первых, давайте отправимся в Autopilot’s Документация И мы, что боты составлены следующим образом:

  • Уникальное имя бота
  • по умолчанию Раздел, который определяет (вы уже догадались) по умолчанию поведение для вашего бота: задача по умолчанию, задача по умолчанию для выполнения ошибок и задачу по умолчанию для запуска в случае, если Соберите Действие терпит неудачу (хорошо, что это происходит позже).
  • таблица стиля Определяет «личность», здесь мы определяем сообщения по умолчанию, чтобы сказать в случае ошибок или успеха, поведение по умолчанию Соберите Действия и голос для бота (это на случай, если мы используем бот для автоматических телефонных звонков).
  • Задачи: задачи (дух) им нужно выполнить; каждый с именем
    • Действия: отдельные действия, которые запускают эти задачи.
    • Образцы: часть разговора, которая запускает эту задачу.
    • Поля: предварительно определенные поля, которые имеют специальную ценность и появятся в ваших образцах (мы также посмотрим, что это за позже)

Я буду объяснен только задачи, необходимые для этого бота, поэтому для полного списка проверьте Документы Анкет

Мы также можем увидеть, что задача – это простая схема JSON и что есть два типа действий:

1) Статический: те, которые определены в схеме бота JSON. 2) Динамика: те, которые возвращаются из API, должны соответствовать схеме JSON.

Как вы, вероятно, уже догадались, статические действия не могут выполнять какую -либо логику: они только запускают, выполняют действия, описанные в схеме, и конец. Если мы хотим сделать какую -либо логику, мы должны использовать динамические действия.

Итак, с учетом этого, давайте посмотрим, какие задачи нам нужны. Для того, чтобы сделать эту статью менее скучной, давайте бросим блок -схему прямо здесь:

Из блоков решений и процессов блок -схемы мы можем легко определить не только количество необходимых действий, но и какие действия динамичны и которые являются статичными.

Статические действия будут:

  • Спросите пользователя, хотят ли он дать нам свое имя; Этот вопрос должен быть разбит на два, мы увидим, почему через мгновение.
  • Действие, которое происходит после Ответ пользователя Блок решения.

Единственным динамическим действием будет приветствие, поскольку нам нужно проверить, находится ли пользователь в базе данных, чтобы создать соответствующее сообщение о приветствии.

Создание начальной схемы

Хорошо, теперь, когда мы определили, сколько действий нам нужно; Давайте создадим фактическую схему, которая описывает нашего бота. В этом посте мы будем писать только статические действия; в то время как динамика будет написана в следующем посте. Прежде всего, вам нужно знать, что есть два способа разработки бота с автопилотом: сначала он находится через панель панели Twilio, а второй – напрямую редактируя схему бота JSON. В этом маленьком проекте мы будем использовать последний.

Настройка схемы

Есть куча Шаблоны готовы к тому, чтобы использовать; Мы будем использовать Helloworld Шаблон, так как другие не совсем соответствуют нашему варианту использования. Так что перейдите по этой ссылке и скачайте Schema.json Файл внутри Помощники/Helloworld Анкет

Давайте откроем файл с нашим любимым редактором, прежде всего: мы изменим имя нашего бота. Что -то вроде Всемогущий бот Подойдет, так что давай пойдем и изменим уникальное имя и FriendlyName Ключи:

{
    "friendlyName" : "The almighty bot",
    "logQueries" : true, // This activates logging messages to the Twilio Dashboard
    "uniqueName" : "almighty-bot"
    // The other stuff
}

Теперь мы увидим, что схема имеет только четыре задачи; два из которых являются запасными действиями в случае ошибки. Давайте напишем статические действия, которые мы определили выше:

Просит имя

Для запроса информации, мы используем Соберите действие. Это действие принимает имя, множество вопросов, которые будут заданы в порядке, который они определены, и on_success перезвонить; которая может быть конечной точкой HTTP или другой задачей.

Помните, я сказал, что это действие должно быть разбито на два? Что ж, представьте, что наш бот просит пользователей об их имени, и пользователь отвечает негативным ответом, что мы делаем? Как указано выше, мы не можем выполнить какую -либо логику в статических действиях; Таким образом, нам нужно позвонить в конечную точку с ответом нашего пользователя (то есть, если они хотят дать нам свое имя или нет) и выполнить соответствующим образом; Так же, как блок -схема выше.

Итак, Let’a добавите нашу первую задачу; Внутри схемы Действия массив добавить:

{
   "uniqueName":"can-have-name",
   "actions":{
      "actions":[
         {
            "collect":{
               "on_complete":{
                  "redirect":{
                     "method":"POST",
                     "uri":"our_super_yet_to_be_endpoint/can-have-name"
                  }
               },
               "name":"ask-for-name",
               "questions":[
                  {
                     "type":"Twilio.YES_NO",
                     "question":"Do you want to tell me your name?",
                     "name":"can_have_name"
                  }
               ]
            }
         }
      ]
   },
   "fields":[
      {
         "uniqueName":"can_have_name",
         "fieldType":"Twilio.YES_NO"
      }
   ],
   "samples":[
      {
         "language":"en-US",
         "taggedText":"{can_have_name}"
      }
   ]
}

Итак, какое волшебство мы только что сделали? Прежде всего, задаче требуется уникальное (удобное для машины) имя. После этого мы пишем действия, которые выполняет задание. В этом случае мы делаем собирать . Наш Соберите задание имеет:

  • Имя: Спросите для имени
  • А on_complete Ключ, действие, которое будет выполнено, когда Соберите заканчивается В этом случае мы инструктируем бота выполнить HTTP -звонок.
  • Во многом вопросах должен возникнуть вопрос:
    • A Тип Анкет
    • Фактический текст вопроса.
    • Имя, это ключ, который мы используем, чтобы анализировать ответы в нашем API; Так что поместите имя для языка программирования.

Обратите внимание, что тип Твилио. Yes_no ; У Autopilot уже есть куча заранее определенных типов для наиболее распространенных вопросов, которые вам нужны. Эти типы уже обучены распознавать естественный язык; Итак, мы будем использовать его, когда сможем.

Наконец, обратите внимание на Поля и образцы Ключи. Как я говорил выше, Поля являются заранее определенными, хорошо, поля, которые действуют как имена переменных и образцы, являются входными данными, которые вызовут эту конкретную задачу. Все действия по сбору должны иметь как минимум один образец (Twilio рекомендует как минимум 6), но, поскольку мы ожидаем только да или нет, мы добавим только один образец, какой образец? Ну, так как мы просто ожидаем да или нет, давайте создадим поле с этим типом и добавьте его в образцы Прилагая имя поля вьющимися скобками. Да, я знаю эту часть с образцами и полями, это неясно в данный момент; Но терпеть меня, с следующей задачей будет ясно.

Теперь давайте добавим фактический вопрос, чтобы задать имя:

 {
   "uniqueName":"store-user",
   "actions":{
      "actions":[
         {
            "collect":{
               "on_complete":{
                  "redirect":{
                     "method":"POST",
                     "uri":"our_super_yet_to_be_endpoint/store-user"
                  }
               },
               "name":"collect-name",
               "questions":[
                  {
                     "type":"Twilio.FIRST_NAME",
                     "question":"Great! What's your name?",
                     "name":"first_name"
                  }
               ]
            }
         }
      ]
   },
   "fields":[
      {
         "uniqueName":"first_name",
         "fieldType":"Twilio.FIRST_NAME"
      }
   ],
   "samples":[
      {
         "language":"en-US",
         "taggedText":"I'm {first_name}"
      },
      {
         "language":"en-US",
         "taggedText":"{first_name} it's what I'm called"
      },
      {
         "language":"en-US",
         "taggedText":"{first_name} is my name"
      },
      {
         "language":"en-US",
         "taggedText":"people call me {first_name}"
      },
      {
         "language":"en-US",
         "taggedText":"people know me as {first_name}"
      },
      {
         "language":"en-US",
         "taggedText":"{first_name}"
      },
      {
         "language":"en-US",
         "taggedText":"my name is {first_name}"
      },
      {
         "language":"en-US",
         "taggedText":"i'm {first_name}"
      }
   ]
}

Теперь, что здесь происходит, это почти то же самое, что мы делали по предыдущей задаче: единственные изменения – это тип вопроса (теперь мы говорим автопилоту попытаться распознать имена), поля и образцы и URI конечной точки Анкет Помните, что поля, как имена переменных? Итак, представьте, что ответы, которые вы ждете, находятся в середине более широкого предложения, например: « Я хотел бы назначить встречу в 3 часа “или” Меня зовут Джон «Именно здесь появляются поля: определяя поле, мы можем написать образцы и сказать автопилот, на какой части образца мы ожидаем, что наш ответ будет. Если мы посмотрим на образцы выше, мы увидим имя поля ( {first_name} ) Мы определили в той части предложения, о котором мы ожидаем, что наш ответ будет; Чем больше образцов, тем лучше. Так что теперь, если наш пользователь пишет что -то вроде ” Меня зовут Джон «; Это запустит « Мое имя {first_name} »

Последнее действие

Это действие, которое будет происходить после того, как пользователь (или нет) дать нам свое имя. Ради простоты, мы будем заполнить:

{
   "uniqueName":"placeholder",
   "actions":{
      "actions":[
         {
            "say":"Almighty bot under construction"
         }
      ]
   },
   "fields":[],
   "samples":[]
}

Здесь мы представляем сказать Это (как вы уже догадались) просто отправляет текст пользователю.

Завершая

Это все для этого поста! Я знаю не так много кода, мы будем писать API, который использует все это в следующем посте; Так что следите за обновлениями

PS: я знаю, мне нужно работать над навыками пост-настройки

Оригинал: “https://dev.to/alessandrojcm/getting-your-user-s-country-and-name-in-a-whatsapp-bot-using-fastapi-and-faunadb-46m”