WIADOMOŚCI

Samouczek PHP– stwórz swoją nową aplikację do obsługi SMS przy użyciu interfejsu API Infobip

Published on:26 / October / 2015

Witamy w samouczku Infobip dla początkujących, w którym przedstawiamy, jak stworzyć własną aplikację sieciową do obsługi SMS. Krok po kroku omówimy proces wdrażania interfejsu API firmy Infobip do obsługi SMS oraz usług SMS-owych. W samouczku przedstawiono trzy przykłady uwzględniające niektóre z głównych funkcji do wysyłania wiadomości SMS i sprawdzania ich statusu:

Zaczniemy od przykładów i prezentacji. Użytkownik będzie mógł następnie sam wybrać, które działanie chce wykonać.

Aby móc na bieżąco korzystać z tego samouczka oraz samodzielnie pisać i testować, trzeba najpierw przygotować otoczenie (i nie chodzi tu o przyciemnienie świateł ani zrobienie kawy smiley). Aby wysyłać wiadomości oraz otrzymywać dzienniki i raporty doręczeń, należy włączyć rozszerzenie php cURLna swoim serwerze sieciowym.

Do celów związanych z tym samouczkiem można skorzystać z rozwiązania z gamy AMP  (wamp, xampp lub innego). Jest to gama programów komputerowych dla różnych systemów operacyjnych, obejmująca serwer sieciowy Apache, bazę danych MySQL oraz obsługę języka programowania PHP. Dla wybranego programu należy włączyć rozszerzenie phpcurl.

Uwaga: Aby wiadomości SMS można było wysyłać bezpiecznie, przykłady te po udostępnieniu powinny być hostowane w protokole HTTPS (przy użyciu TLS).  Dla uproszczenia w tym samouczku użyliśmy zwykłego protokołu HTTP.

 

 Pełnofunkcyjna wiadomość tekstowa 

Strona pełnofunkcyjnej wiadomości tekstowej (advancedSms.php) zawiera formularz do wysłania wiadomości. Przycisk Wyślij (Submit) wyśle żądanie do strony wskazanej w atrybucie action formularza. W tym przykładzie wyśle je do siebie.

  <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="POST" ... >

Budowanie żądania

Zanim użytkownik zacznie manipulować wartościami, powinien sprawdzić, czy są one prawidłowo ustawione. W tym przykładzie zaznaczyliśmy tylko pole „toInput”. Nie trzeba zaznaczać wszystkich pól, ponieważ metoda POST HTTP ustawi wszystko automatycznie (jeśli którekolwiek pole do wprowadzenia danych będzie puste, jego wartość stanowić będzie pusty ciąg). Przy pierwszym ładowaniu strony należy pamiętać, że żadne z tych pól nie będzie występować. Jeszcze tylko dwa kroki i wszystko będzie ustawione. Po zaznaczeniu pól należy zdefiniować URL dla żądania wysłania, a także treść żądania, które zostanie wysłane. Treść żądania POST zostanie przedstawiona jako ciąg JSON. Tworzenie treści żądania będzie wyglądać następująco:

 // URL for sending request
$postUrl = "https://api.infobip.com/sms/1/text/advanced";

// creating an object for sending SMS
$destination = array("messageId" => $messageId, 
            "to" => $to);
$message = array("from" => $from,
        "destinations" => array($destination),
        "text" => $text,
        "notifyUrl" => $notifyUrl,
        "notifyContentType" => $notifyContentType,
        "callbackData" => $callbackData);
$postData = array("messages" => array($message));
// encoding object
$postDataJson = json_encode($postData)

W tym przykładzie SMS wysyłany jest tylko do jednego miejsca docelowego. Aby wysłać tę wiadomość do wielu miejsc docelowych, wystarczy stworzyć kolejny obiekt miejsca docelowego (destination) i dodać go do tablicy miejsc docelowych (destinations).

Ponieważ „to” (do) jest jedynym wymaganym polem, przed wysłaniem żądania należy sprawdzić, czy jest ono puste. Jeśli jest puste, należy pominąć całą logikę i poinformować swojego użytkownika o brakującym polu.

if (isset($_POST['toInput'])) { 
// all the logic goes here 
}

Do wysłania żądania wybraliśmy cURL.

 $ch = curl_init();
$header = array("Content-Type:application/json", "Accept:application/json");

curl_setopt($ch, CURLOPT_URL, $postUrl);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($ch, CURLOPT_MAXREDIRS, 2);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postDataJson);

// response of the POST request
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$responseBody = json_decode($response);
curl_close($ch);

W zacytowanym kodzie wykorzystaliśmy wiele opcji ustawienia żądania, które inicjuje się metodą  curl_init():

  • CURLOPT_URL - ustawienie URL zawierającego punkt końcowy metody
  • CURLOPT_HTTPHEADER - nagłówki rodzaju treści i akceptacji żądania
  • CURLOPT_HTTPAUTH, CURLOPT_USERPWD - rodzaj uwierzytelnienia, nazwa użytkownika i hasło
  • CURLOPT_POST - użyta metoda HTTP – POST
  • CURLOPT_POSTFIELDS - uprzednio zbudowany ciąg o strukturze XML lub JSON
  • Tutaj można zobaczyć inne opcje cURL do wysyłania.

Po ustawieniu wszystkich opcji należy wykonać żądanie przy użyciu metody curl_exec($ch). Metoda ta dostarczy odpowiedź, która może zostać przedstawiona jako JSON i posłużyć do przyszłego parsowania. Po wykonaniu żądania dostępne będą informacje o kodzie odpowiedzi HTTP, które wykorzystamy w dalszej części tego samouczka -curl_getinfo($ch, CURLINFO_HTTP_CODE).

Parsowanie odpowiedzi

Jeśli wszystko poszło dobrze i otrzymano kod odpowiedzi HTTP z rodziny 2xx (200 OK, 201 CREATED itp.), można zaczerpnąć potrzebne informacje z treści odpowiedzi i przedstawić je swojemu użytkownikowi. W naszym przykładzie postanowiliśmy przedstawić: Message ID, To, SMS Count, Status Group, Status Group Name, Status ID, Status Name oraz Status Description, ale można wybrać dowolne informacje.

Pętla foreach przedstawiona poniżej przeiteruje tablicę odpowiedzi na wysłane wiadomości i napisze pojedynczy rząd dla każdej z wysłanych wiadomości:

if ($httpCode >= 200 && $httpCode < 300) {
        $messages = $responseBody->messages;        

        ...

        foreach ($messages as $message) {
            echo "";
            echo "" . $message->messageId . "";
            echo "" . $message->to . "";
            echo "" . $message->status->groupId . "";
            echo "" . $message->status->groupName . "";
            echo "" . $message->status->id . "";
            echo "" . $message->status->name . "";
            echo "" . $message->status->description . "";
            echo "" . $message->smsCount . "";
            echo "";
        }
}

Uwaga: W tym przykładzie wyślemy tylko jedną wiadomość do jednego miejsca docelowego, więc tablica odpowiedzi na wysłane wiadomości będzie zawierać tylko jeden element i nie ma potrzeby jej pętlować. Jeśli jednak użytkownik postanowi wysłać wiadomość do więcej niż jednego miejsca docelowego, powinien przeiterować tablicę odpowiedzi.

W przypadku wystąpienia wyjątku, wiadomość można przedstawić swojemu użytkownikowi w następujący sposób:

<div class="alert alert-danger" role="alert">
    <b>An error occurred!</b> Reason:
    <?php
    echo $responseBody->requestError->serviceException->text;
    ?>
</div>

Dzienniki wysłanych wiadomości

Po wybraniu tej opcji otworzy się strona logs.php z formularzem do wprowadzenia danych w celu otrzymywania dzienników wysłanych wiadomości. Przycisk Wyślij (Submit) wyśle (POST) te pola do siebie.

Budowanie żądania

logs.php to strona, na której przedstawione będą dzienniki wysłanych wiadomości. Należy zdefiniować URL dla żądania wysłania zawierający punkt końcowy dzienników wiadomości oraz wysłać do niego żądanie, tym razem przy użyciu metody HTTP GET (opcja CURLOPT_HTTPGET ustawiona na TRUE):

 

$getUrl = 'https://api.infobip.com/sms/1/logs?limit=20';

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $getUrl);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Accept: application/json'));
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $username . ":" . $password);
curl_setopt($curl, CURLOPT_HTTPGET, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$responseBody = json_decode($response);
curl_close($curl);

Po wykonaniu żądania culr_exec($curl) i otrzymaniu kodu odpowiedzi HTTP można rozpocząć parsowanie treści w zależności od wartości kodu, podobnie jak zrobiliśmy to w rozdziale poświęconym pełnofunkcyjnym wiadomościom tekstowym.

Parsowanie odpowiedzi

Jeśli wszystko poszło dobrze i otrzymano kod odpowiedzi HTTP z rodziny 2xx (200 OK, 201 CREATED itp.), można zaczerpnąć potrzebne informacje z treści odpowiedzi i przedstawić je swojemu użytkownikowi. W naszym przykładzie wybraliśmy: Message ID, To, From, Text, Status Group Name, Status Description i Sent At, ale można wybrać dowolne informacje, tak jak wcześniej:

if ($httpCode >= 200 && $httpCode < 300) {
    $logs = $responseBody->results;

    ...

    foreach ($logs as $log) {
        echo "";
        echo "" . $log->messageId . "";
        echo "" . $log->to . "";
        echo "" . $log->from . "";
        echo "" . $log->text . "";
        echo "" . $log->status->groupName . "";
        echo "" . $log->status->description . "";

        $formattedSentAt = date("M d, Y - H:i:s P T", strtotime($log->sentAt));    
        echo "" . $formattedSentAt . "";
        echo "";         
    }
}

Następna pętla foreach przeiteruje tablicę dzienników wysłanych wiadomości i napisze w nich pojedynczy rząd z odpowiednimi kolumnami. W tym przypadku pętla foreach jest niezbędna, ponieważ poprosiliśmy o odzyskanie wszystkich dzienników wiadomości.

Na koniec można sparsować treść żądania, jeśli wystąpił wyjątek, tak jak zrobiliśmy to w przypadku metody wysyłania wiadomości:

<div class="alert alert-danger" role="alert">
    <b>An error occurred!</b> Reason:
    <?php
        echo $responseBody->requestError->serviceException->text;
    ?>
</div>

Ta funkcja różni się nieco od dwóch poprzednich – strona dlrPush.php nie służy do żądania danych, tylko na nie czeka. Gdy dane zostaną wypchnięte na tę stronę, można je sparsować i odpowiednio przedstawić swojemu użytkownikowi.

Uwaga: Raporty doręczeń są wypychane ze strony pełnofunkcyjnych wiadomości tekstowych poprzez wpisanie URL tej strony w polu Notify URL. Ponadto pole Notify ContentType na tej stronie definiuje, który rodzaj treści ma się pojawić.

 

Otrzymywanie wypchniętego raportu doręczeń

$responseBody = file_get_contents('php://input');

if ($responseBody <> "") {
    if (isJson($responseBody)) {
        $responseJson = json_decode($responseBody);
        $results = $responseJson->results;
    } else if (strpos(trim($responseBody), '<reportResponse>') == 0) {
        $responseXml = simplexml_load_string($responseBody);
        $results = $responseBody->results->result;
    }
}

Powyższy kod wskazuje, że do pozyskania surowych danych POST w formie ciągu używana jest metoda file_get_contents('php://input').Kolejne wiersze informują, jak sprawdzić, czy dane są parsowane jako XML, czy JSON, a także jak wydobyć wypchnięte raporty doręczeń.

W przypadku XML sprawdzamy, czy ciąg treści odpowiedzi zaczyna się od <reportResponse> i jeśli nie, próbujemy zdekodować go bez błędów – funkcja isJson(). Jeśli wszystkie warunki są FALSE, zmienna $result pozostaje nieustawiona, co oznacza, że powinniśmy powiedzieć użytkownikowi, że żaden raport doręczenia nie został wypchnięty na serwer callback.

Parsowanie wyniku

Parsowanie wypchniętych raportów doręczeń jest bardzo podobne do parsowania odpowiedzi w metodzie pełnofunkcyjnej wiadomości tekstowej i dzienników wysłanych wiadomości, poza tym że nie sprawdzamy kodu odpowiedzi HTTP (bo nie ma żadnej odpowiedzi). Wystarczy tylko wybrać, które informacje z wypchniętych raportów doręczeń chcemy pokazać i wpisać to na stronie.