Como usar o Google Sheets como um banco de dados para seu app PHP

January 16, 2019
Escrito por
Charles Oduk
Contribuidor
As opiniões expressas pelos colaboradores da Twilio são de sua autoria

Como usar o Google Sheets como um banco de dados para seu app PHP

Introdução

Há doze anos, o Google teve, na minha opinião, a ideia ambiciosa de lançar um produto que estaria em concorrência direta com o Excel. Desde então, o Google Sheets ganhou popularidade e tornou-se muito mais do que apenas uma planilha. Por ser um aplicativo on-line, é muito mais fácil integrá-lo às suas diferentes ferramentas on-line. Neste tutorial, testaremos a flexibilidade do Sheets buscando dados da API do Order Desk, atualizando uma planilha do Google e enviando uma confirmação da Twilio via SMS. Usaremos o Order Desk para simular um sistema de atendimento de uma loja virtual, que faz o backup de seus dados em uma planilha do Google. 

Requisitos do tutorial

Para este tutorial, você precisará do seguinte:

Configuração do ambiente de desenvolvimento

Para começar, vamos criar um diretório de projetos e um arquivo .env dentro dele.

Instalar dependências

Para este projeto, precisamos de três dependências:

No terminal, dentro do diretório de projetos, execute o comando:

$ composer require vlucas/phpdotenv google/apiclient twilio/sdk

A próxima etapa é criar um arquivo .env e copiar estas variáveis nele:

ORDER_DESK_API_KEY=
ORDER_DESK_STORE_ID=

TWILIO_TOKEN=
TWILIO_SID=
TWILIO_NUMBER=

GOOGLE_APPLICATION_CREDENTIALS=./credentials.json
GOOGLE_API_KEY=

GOOGLE_SERVICE_ACCOUNT_NAME=
GOOGLE_SERVICE_KEY=
SPREADSHEET_ID=

Vamos trabalhar etapa por etapa para obter os valores das variáveis acima.

Credenciais do Order Desk

Caso não tenha uma conta do Order Desk, crie uma. No menu do dashboard, em Settings (Configurações), clique em Store Settings (Configurações da loja). A guia API está localizada na extremidade direita do menu Store Settings (Configurações da loja). Clique nela. Em seguida, crie sua API key (chave de API). Copie a store ID (ID da loja) e a API key (chave de API) no arquivo .env.

Credenciais da Twilio

Em sua conta da Twilio, crie um projeto em "Programmable SMS" (SMS programável). Após configurar o projeto, copie o Account SID (SID da conta) e o Auth Token (Token de autenticação), localizados à direita. Para obter seu número de telefone, navegue até Phone Numbers (Números de telefone). Copie-o e cole no arquivo .env.

Home do console da Twilio

Credenciais do Google

Em seguida, precisamos criar um projeto do Google e ativar a API do Google Sheets. Temos interações entre servidores em nosso projeto, portanto, precisamos de uma conta de serviço para usar o OAuth 2.0. Para obter mais informações, leia a documentação.

No dashboard do projeto, à esquerda, clique no menu de hambúrguer. Navegue até IAM & admin (IAM e administrador) -> Service Accounts (Contas de serviço).

Tela de configuração de acesso do Google Cloud

Em seguida, clique em "Create Service Account" (Criar conta de serviço). Na primeira etapa, insira o Service Account (nome da conta de serviço). Nomeei a minha como twilio-sheets (Planilhas da Twilio). Insira os detalhes obrigatórios. Você pode ignorar as solicitações opcionais. Na terceira etapa, clique em "Create Key" (Criar chave).. Por padrão, a chave será criada como um arquivo JSON e baixada no computador. Copie esse arquivo no diretório raiz do projeto e renomeie-o como credentials.json.

Nota: esse é um arquivo confidencial e não deve ser enviado a um repositório público.

Após clicar em Done (Concluído), copie a Key ID (ID da chave) na variável GOOGLE_SERVICE_KEY no arquivo .env. Da mesma forma, copie o e-mail e salve-o como o valor da variável GOOGLE_SERVICE_ACCOUNT_NAME. Em seguida, vamos navegar até Credentials (Credenciais). Clique em "Create Credentials" (Criar credenciais) e crie uma API key (chave de API). Assim que o fizer, copie-a e cole como um valor da variável GOOGLE_API_KEY.

Por fim, no Google Drivecrie uma planilha do Google e nomeie-a. Nomeei a minha como "Order Desk Data" (Dados do Order Desk). No canto superior direito da planilha, clique em Compartilhar e altere a permissão para "qualquer pessoa com o link pode editar". A URL deve ter a seguinte aparência:

https://docs.google.com/spreadsheets/d/1Io5ko9zaOm7nnEKVpz84NLdFdrtdVnr9TQFRrGVEuvM/edit#gid=0

A seção 1Io5ko9zaOm7nnEKVpz84NLdFdrtdVnr9TQFRrGVEuvM é nossa ID da planilha. Copie sua ID e salve-a no arquivo .env. Neste ponto, todas as variáveis de ambiente devem ser preenchidas.

Na primeira linha, adicione os seguintes cabeçalhos nas seis primeiras colunas:

  • First Name (Nome)
  • Last Name (Sobrenome)
  • Email (E-mail)
  • Shipping Method (Método de envio)
  • Payment Type (Tipo de pagamento)
  • Order Total (Total do pedido)

Exemplo de planilha do Google

Estas são as colunas que atualizaremos usando nosso código.

O código

Cliente de API do Order Desk

O Order Desk fornece um cliente auxiliar para o desenvolvimento de PHP disponível no Github. Vamos criar um arquivo chamado OrderDeskClient.php e copiar o seguinte código nele:

<?php

class OrderDeskApiClient
{
    private $store_id;
    private $api_key;
    private $base_url = "https://app.orderdesk.me/api/v2";
    public $last_status_code = "";

    public function __construct( $store_id, $api_key ) {
        $this->store_id = $store_id;
        $this->api_key = $api_key;
    }

    public function get( $url = "", $post = null ) {
        return $this->go( "GET", $url, $post );
    }

    public function post( $url, $post = null ) {
        return $this->go( "POST", $url, $post );
    }

    public function put( $url, $post = null ) {
        return $this->go( "PUT", $url, $post );
    }

    public function delete( $url, $post = null ) {
        return $this->go( "DELETE", $url, $post );
    }

    public function go( $method, $url, $post ) {
        if ( ! is_array( $post ) ) {
            $post = null;
        }
        if ( ! $url ) {
            throw new \Exception( "Please enter a destination url" );
        }

        $url =  $this->base_url . "/" . $url;
        $headers = $this->getHeaders();

        //GET Override
        if ( $method == "GET" && $post !== null ) {
            $url .= (strpos($url, "?") === false ? "?" : "") . http_build_query( $post );
            $post = "";
        }

        //Setup cURL
        $ch = curl_init();
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
        curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method );
        if ( $post ) {
            curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $post ) );
        }
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
        curl_setopt( $ch, CURLOPT_TIMEOUT, 10 );
        curl_setopt( $ch, CURLOPT_USERAGENT,  "orderdesk/orderdesk_client" );

        //Send To Order Desk and Parse Response
        $response = trim( curl_exec( $ch ) );
        $info = curl_getinfo( $ch );
        $json = json_decode( $response, 1 );

        if ( ! is_array( $json ) ) {
            return $response;
        }

        $this->last_status_code = $info[ 'http_code' ];
        return $json;
    }

    //Get auth headers for this call
    public function getHeaders() {
        return array(
            "ORDERDESK-STORE-ID: {$this->store_id}",
            "ORDERDESK-API-KEY: {$this->api_key}",
            "Content-Type: application/json",
        );
    }

    //Check Post JSON
    public function validatePostedJson() {

        if ( ! isset( $_POST[ 'order' ] ) ) {
            header( ':', true, 400 );
            die( 'No Data Found' );
        }

        //Check Store ID
        if ( ! isset( $_SERVER[ 'HTTP_X_ORDER_DESK_STORE_ID' ]) || $_SERVER[ 'HTTP_X_ORDER_DESK_STORE_ID' ] != $this->store_id ) {
            header( ':', true, 403 );
            die( 'Unauthorized Request' );
        }

        //Check the Hash
        if ( ! isset( $_SERVER[ 'HTTP_X_ORDER_DESK_HASH' ]) || hash_hmac( 'sha256', rawurldecode( $_POST[ 'order' ] ), $this->api_key ) != $_SERVER[ 'HTTP_X_ORDER_DESK_HASH' ] ) {
            header( ':', true, 403 );
            die( 'Unauthorized Request' );
        }

        //Check Order Data
        $order = json_decode( $_POST[ 'order' ], 1 );
        if ( ! is_array( $order ) ) {
            header( ':', true, 400 );
            die( 'Invalid Order Data' );
        }
    }
}

Cliente do Google Sheets

Usando a API spreadsheets.values.update, podemos criar um cliente do Google Sheets. Crie um arquivo, nomeie-o como GoogleSheetsClient.php e copie o seguinte código:

<?php

require __DIR__ . '/vendor/autoload.php';

class GoogleSheetsClient
{
   protected $service;

   /**
    * GoogleSheetsClient constructor
    */
   public function __construct()
   { 
       $apiKey = getenv( 'GOOGLE_API_KEY' );

       $client = new Google_Client();
       $client->setAccessType( 'offline' );
       $client->useApplicationDefaultCredentials();
       $client->setDeveloperKey( $apiKey );
       $client->setSubject( getenv( 'GOOGLE_SERVICE_ACCOUNT_NAME' ) );
       $client->setScopes( [ 'https://www.googleapis.com/auth/spreadsheets' ] );

       $this->service = new Google_Service_Sheets( $client );
   }

   /**
    * Creates an event
    *
    * @param array $eventDetails event details e.g summary, start, end, attendees, e.t.c
    *
    * @return array $user of a user
    */
   public function updateSheet( $values, $range, $spreadsheetId )
   {

       $requestBody = new Google_Service_Sheets_ValueRange( [
           'values' => $values
       ] );

       $params = [
           'valueInputOption' => 'USER_ENTERED'
       ];

      return $this->service->spreadsheets_values->update( $spreadsheetId, $range, $requestBody, $params );
   }
}

No construtor, primeiro autenticamos usando as credenciais que recebemos anteriormente do Google. O método updateSheet tem a lógica que atualiza a planilha com base nos parâmetros estabelecidos para ela.

Classe de pedido

Até aqui, criamos clientes que facilitam o uso do Order Desk e do Google Sheets. Agora, precisamos criar uma classe que injete os clientes, busque dados do Order Desk, atualize o Google Sheet e envie um Twilio SMS.

Crie um arquivo chamado Order.php e copie o seguinte código:

<?php

class Order
{
  private $googleSheets;
  private $orderDesk;
  private $twilio;

  public function __construct( GoogleSheetsClient $googleSheets, OrderDeskApiClient $orderDesk, Twilio\Rest\Client $twilio )
  {
      $this->googleSheets = $googleSheets;
      $this->orderDesk    = $orderDesk;
      $this->twilio       = $twilio;
  }

  /**
   * Gets orders from OrderDesk
   *
   * @return void
   */
  public function getOrders()
  {
      $response = $this->orderDesk->get( "orders" );
      $orders   = $response[ "orders" ];
      $values   = [];

      if (!empty($orders)) {
           foreach ( $orders as $order ) {

               $value = [
                   $order["shipping"]["first_name"],
                   $order["shipping"]["last_name"],
                   $order["email"],
                   $order["shipping_method"],
                   $order["payment_type"],
                   $order["order_total"]
               ];
  
               array_push( $values, $value );
           }
  
           $this->updateGoogleSheets( $values );
       } else {
           return $response['message'];
       }
  }

  /**
   * Updates Google Sheets
   *
   * @param array $values - values of the fields that need
   * to be updated on Sheets
   *
   * @return void
   */
  public function updateGoogleSheets( $values )
  {
  
      $spreadsheetId = getenv( "SPREADSHEET_ID" );
      $range         = 'Sheet1!A2:F2';

      $response = $this->googleSheets->updateSheet( $values, $range,$spreadsheetId );

      if ( $response->updatedRows ) {
          $this->sendSms( $response->updatedRows );
          return "Congratulations, $response->updatedRows row(s) updated on Google Sheets";
      }
  }

  /**
   * Sends an SMS about the update on Sheets
   *
   * @param integer $numberOfRows - number of rows
   *
   * @return void
   */
  public function sendSms( $numberOfRows )
  {
      $myTwilioNumber = getenv( "TWILIO_NUMBER" );

      $this->twilio->messages->create(
          // Where to send a text message
          "INSERT VERIFIED NUMBER",
          array(
             "from" => $myTwilioNumber,
             "body" => "Hey! $numberOfRows row(s) updated on Google Sheets!"
         )
      );
  }
}

Atualize o código acima com um número para o qual deseja enviar mensagens SMS. As mensagens SMS só poderão ser enviadas para uma conta verificada se você estiver usando uma conta de avaliação.

Colocar tudo para funcionar

É necessário vincular os arquivos que criamos para que eles funcionem. Vamos criar um arquivo chamado index.php e copiar o seguinte código nele:

<?php
require __DIR__ . "/vendor/autoload.php";

require "GoogleSheetsClient.php";
require "OrderDeskClient.php";
require "Order.php";

use Twilio\Rest\Client as TwilioClient;

$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();


$apiKey    = getenv( "ORDER_DESK_API_KEY" );
$storeId   = getenv( "ORDER_DESK_STORE_ID" );
$orderDesk = new OrderDeskApiClient( $storeId, $apiKey );

$twilioAccountSid = getenv( "TWILIO_SID" );
$twilioAuthToken  = getenv( "TWILIO_TOKEN" );
$twilio           = new TwilioClient( $twilioAccountSid, $twilioAuthToken );

$googleSheets = new GoogleSheetsClient();

$order = new Order( $googleSheets, $orderDesk, $twilio );

$result = $order->getOrders();

echo $result;

Quando iniciamos nosso aplicativo, esse arquivo cria objetos e chama a função getOrders() na classe de Order.

Nota: é importante mencionar que esse formato é ideal apenas para um aplicativo pequeno. À medida que um aplicativo cresce, mais objetos precisam ser criados em sua inicialização e isso pode afetar seu desempenho. É possível solucionar isso obtendo um aplicativo de injeção de dependência, que lê um arquivo XML. Os objetos seriam serializados e gravados em um arquivo. O arquivo index.php simplesmente leria esse arquivo e criaria os objetos diretamente.

Testar o aplicativo

Antes de testar o aplicativo, precisamos criar um pedido no Order Desk. No dashboard, crie um pedido e salve.

No diretório de projetos, execute o comando:

php index.php

Agora, sua planilha será atualizada e você receberá um SMS confirmando a atualização bem-sucedida.

Planilha do Google com um registro preenchido

Parcial da tela do celular mostrando a mensagem recebida

Conclusão

Parabéns! Você atualizou com sucesso uma planilha do Google com dados da API do Order Desk e enviou um SMS de confirmação usando a plataforma da Twilio. É possível tornar esse aplicativo ainda melhor, configurando um cron job para verificar pedidos em determinados intervalos.

Gif Like a Boss

Estou ansioso para saber mais sobre o aplicativo incrível que você criou. Encontre o código completo no Github.

Este artigo foi traduzido do original "How to use Google Sheets as a Database for your PHP App". Enquanto melhoramos nossos processos de tradução, adoraríamos receber seus comentários em help@twilio.com - contribuições valiosas podem render brindes da Twilio.