W tej części serii „Jak zbudować chatbota dla Messengera w PHP” dodamy kilka bardziej zaawansowanych odpowiedzi. Pobierzemy podstawowe informacje o użytkowniku, wyświetlimy pogodę i dodamy załączniki. Zaczynajmy.

Dostosowanie struktury webhook.php

Zanim przejdziemy do dodawania bardziej zaawansowanych odpowiedzi, musimy zmienić jedną rzecz. Obecną konstrukcję kodu możemy podzielić na 3 części:

  1. Odebranie wiadomości
  2. Przygotowanie odpowiedzi
  3. Przesłanie odpowiedzi

Teraz ta struktura działa w porządku, bo generujemy tylko tekstowe odpowiedzi. Problem pojawi się przy wysyłaniu np. zdjęć lub przycisków, bo konstrukcja zmiennej $jsonData będzie się znacznie różniła. Rozwiążemy to tworząc tą zmienną wewnątrz utworzonych wcześniej if i else.

Jeśli nie wiesz dokładnie, co masz zmienić, to pobierz poprawioną wersję i przejdź dalej.

Pobranie informacji o użytkowniku

Facebook umożliwia pobranie podstawowych danych o użytkowniku, który wysyła wiadomość do bota. Możemy pobrać:

  • imię
  • nazwisko
  • zdjęcie profilowe
  • język
  • strefę czasową
  • płeć

W tym przykładzie użyjemy tylko imienia, ale reszta jest pobierana na tej samej zasadzie. Chcemy wyświetlić imię w przywitaniu, więc zaraz po $message_to_reply = ”; dopisujemy:

$user_info_url = "https://graph.facebook.com/v2.6/".$sender."?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=".$access_token;
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $user_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$result = curl_exec($ch);

curl_close ($ch);

$user = json_decode($result);

W zmiennej $user_info_url zapisujemy URL do przesłania żądania. Obowiązkowo musimy tutaj podać id usera ($sender), wybrane informacje (fields) i access_token, który pobieramy z utworzonej w poprzedniej części kursu zmiennej.

Następnie przesyłamy żądanie i zapisujemy wynik w zmiennej $result. W $user dekodujemy wynik z formatu JSON. Dopiszmy teraz imię użytkownika do przywitania:

if(preg_match('[cześć|dzień dobry|witam]', strtolower($message))) {
    $array = ['Dzień dobry', 'Witam', 'Cześć', 'Hej'];
    $message_to_reply = $array[array_rand($array)]." ".$user->first_name;
}

Wykonujemy standardową aktualizacje:

git add .
git commit -am "dodanie imienia"
git push heroku master

Możemy teraz przetestować chatbota:

powitanie imie

Wyświetlanie imienia działa poprawnie. Jeśli chciałbyś pobrać inną informację (np. nazwisko), to wystarczy użyć $user->nazwa_parametru ($user->last_name).

Wyświetlenie pogody

Dodamy teraz możliwość pobrania aktualnej pogody dla dowolnego miasta. Pomoże nam w tym API OpenWeatherMap. Musimy zacząć od utworzenia darmowego konta by uzyskać klucz weryfikacyjny. Przejdź na tę stronę i zarejestruj się:

weather rejestracja

Po rejestracji  zostaniesz przeniesiony do profilu. Wybierz zakładkę API Keys i skopiuj wygenerowany klucz:

api keys

Wróćmy teraz do webhook.php. Pomiędzy if a else dodajemy kolejny warunek:

elseif(preg_match('[pogoda w|prognoza pogody w]', strtolower($message))) {

  // pobranie nazwy miasta z wiadomości
  $get_city = explode(' w ', $message);
  $city = $get_city[1];

  $weather_url = "http://api.openweathermap.org/data/2.5/weather?q=".$city."&units=metric&lang=pl&appid=06e3909fc70bbc87xxxxxxxxxxxxx";

  function get_http_response_code($url) {
      $headers = get_headers($url);
      return substr($headers[0], 9, 3);
  }

  if(get_http_response_code($weather_url) == "200") {

    $weather_json = file_get_contents($weather_url);
    $weather = json_decode($weather_json, true);

    // pobranie aktualnej temperatury
    $temp = $weather['main']['temp'];
    // pobranie zachmurzenia w procentach
    $clouds = $weather['clouds']['all'];
    // pobranie prędkości wiatru w m/s
    $wind = $weather['wind']['speed'];

    $message_to_reply = "Temperatura w ".$city." wynosi ".$temp. " stopni Celcjusza. ".
    "Niebo jest zachmurzone w ".$clouds."%. Wiatr wieje z prędkością ".$wind." m/s.";

  } else {
    $message_to_reply = 'Nie mogliśmy pobrać pogody. Wpisz "Pogoda w [nazwa miasta]".';
  }


  $jsonData = '{
      "recipient":{
          "id":"'.$sender.'"
      },
      "message":{
          "text":"'.$message_to_reply.'"
      }
  }';

}

Kod zostanie wykonany jeśli w wiadomości użytkownika znajdzie się „pogoda w” lub „prognoza pogody w”. Jeśli ten warunek jest spełniony, to wyciągamy nazwę miasta z wiadomości i zapisujemy w zmiennej $city.

Następnie przesyłamy żądanie do OpenWeatherMap. Pamiętaj, żeby dodać tutaj skopiowany wcześniej appid. Następnie sprawdzamy czy żądanie zakończyło się sukcesem (200). Wtedy prognozę zapisujemy w zmiennej $weather. Teraz możemy z $weather wyciągnąć kolejno temperaturę, zachmurzenie i prędkość wiatru. Tworzymy komunikat i zapisujemy w wiadomości.

Jeśli żądanie się nie powiodło, to wyświetlamy komunikat o błędzie.

Zaktualizujmy aplikację:

git add .
git commit -am "prognoza pogody"
git push heroku master

Testujemy chatbota:

pogoda

Możesz zauważyć, że pogoda wyświetli się również dla odmiany nazwy miasta np. Kraków i Krakowie.

Przesyłanie zdjęć

Kolejną rzeczą, którą umożliwia nam Facebook, jest przesyłanie do użytkownika zdjęć. Dodajmy nowy elseif pod pogodą:

elseif(preg_match('[zdjęcie|obrazek]', strtolower($message))) {

    $jsonData = '{
        "recipient":{
            "id":"'.$sender.'"
        },
        "message":{
            "attachment":{
              "type":"image",
              "payload":{
                "url":"https://devcorner.pl/wp-content/uploads/2017/02/messenger-840x500.jpg"
              }
            }
        }
    }';
}

Konstrukcja message znacznie różni się od poprzedniej. Dodajemy tutaj załącznik (attachment). Typ ustawiamy na image. Wewnątrz url podajemy link do zdjęcia.

Wykonujemy aktualizację Heroku:

git add .
git commit -am "dodanie imienia"
git push heroku master

Wyślijmy teraz wiadomość do chatbota:

zdjęcie

Wysyłanie plików

Wysyłanie plików działa na podobnej zasadzie jak zdjęcia. Dodajmy kolejny warunek:

elseif(preg_match('[regulamin]', strtolower($message))) {

    $jsonData = '{
        "recipient":{
            "id":"'.$sender.'"
        },
        "message":{
        "attachment":{
          "type":"file",
          "payload":{
            "url":"https://devcorner.pl/wp-content/uploads/2017/02/regulamin.pdf"
          }
        }
      }
    }';

}

Typ załącznika (type) musimy zmienić na file. W url standardowo podajemy adres załącznika. Wykonajmy aktualizację:

git add .
git commit -am "dodanie zalacznika"
git push heroku master

I wykonajmy test:

regulamin

Przyciski

API Messengera umożliwia dodawanie przycisków do wiadomości. Dodajmy kolejny elseif:

elseif(preg_match('[opcje|co mogę zrobić]', strtolower($message))) {

    $jsonData = '{
        "recipient":{
            "id":"'.$sender.'"
        },
        "message":{
        "attachment":{
          "type":"template",
          "payload":{
            "template_type":"button",
            "text":"Co chcesz zrobić?",
            "buttons":[
              {
                "type":"web_url",
                "url":"https://devcorner.pl/zbudowac-chatbota-dla-messengera-php-2-nawiazanie-komunikacji/",
                "title":"Najnowszy wpis"
              },
              {
                "type":"web_url",
                "url":"https://devcorner.pl",
                "title":"Strona główna"
              },
            ]
          }
        }
      }
    }';

}

Ten kod wygeneruje 2 buttony – Najnowszy wpis i Strona główna, które przenoszą użytkownika do artykułu i strony głównej. Kolejne przyciski możesz dodawać wpisując:

{
     "type":"web_url",
     "url":"http://adres.pl",
     "title":"Tytuł"
}

Wykonajmy aktualizację:

git add .
git commit -am "buttony"
git push heroku master

I przetestujmy bota:

opcje

 

To wszystko w tej części kursu. Masz pytania lub uwagi? Napisz w komentarzu.

Pobierz gotową paczkę.

  • Tomek2525

    Hej! Bot działa tylko gdy to ja do niego napiszę, jeżeli pisze do niego ktokolwiek inny, to nie odpisuje. Aplikacja jest publiczna. Co z tym zrobić?

  • ShadowS

    Pytanie można połączyć jeszcze yt albo spotify?

  • Kruku

    Cześć, super tutorial, udało mi się zrobić dwie pierwsze części, tutaj natomiast mam problem taki, że bo w odpowiedzi nie wyświetla imienia rozmówcy. Czy może to być błąd w tej linijce:
    user_info_url = „https://graph.facebook.com/v2.6/”.$sender.”?
    bo teraz jest już chyba wersja 2.8, ale sama zmiana cyferki nie pomogła. Co to może być innego?
    Pozdrawiam