2014-10-03 99 views
0

我試圖使用下面的代碼連接到curl命令的sendgrid,並使用foreach將結果發佈到我的數據庫。現在,我的用戶名和密碼出現未定義的索引錯誤,而且我的foreach上也有一個無效的參數。我相信我知道爲什麼我得到的foreach錯誤,我有它在我的代碼中評論,但我不確定通過web api的連接方面。謝謝Sendgrid - PHP - 將json數據發佈到我的數據庫

*編輯 - 我只想補充說,我的端點設置,我能夠通過ngroks網頁界面看到測試數據。

<?php 

require_once('../functions.php'); 
session_start(); 
connect(); 

//Enable Connection to Event Notifications 
    $url = 'https://api.sendgrid.com/'; 
    $user = $_SESSION["xxxxxxx"]; 
    $pass = $_SESSION["xxxxxxx"]; 
    $params = array(
     'api_user' => $user, 
     'api_key' => $pass, 
     'name' => 'eventnotify' //API App Name 
    ); 
    $request = $url . 'api/filter.activate.json'; //i believe the [module] and [action] is incorrect here. 

// Generate first curl request 
    $session = curl_init($request); 

// Tell curl to use HTTP POST 
    curl_setopt($session, CURLOPT_POST, true); 

// Tell curl that this is the body of the POST 
    curl_setopt($session, CURLOPT_POSTFIELDS, $params); 

// Tell curl not to return headers, but do return the response 
    curl_setopt($session, CURLOPT_HEADER, false); 
    curl_setopt($session, CURLOPT_RETURNTRANSFER, true); 

// obtain response 
    $response = curl_exec($session); 
    curl_close($session); 


    $data = $response[file_get_contents("php://input")]; // Can i do this? Or do i just pass a $json variable? 
    $records = json_decode($data, true); 

    foreach ($records as $record) { 
     // Here, you now have each event and can process them how you like 
     echo getArray($record); 
     $email = isset($record['email']) ? $record['email'] : null; 
     $event = $record['event']; 

     $uid = $_POST['uid']; 
     $timestamp = $_POST['timestamp']; 
     $event_type = $_POST['event']; 
     $email_address = $_POST['email']; 
     $smtpid = $_POST['smtpid']; 
     $sg_event_id = $_POST['sg_event_id']; 
     $sg_message_id = $_POST['sg_message_id']; 
     $category = $_POST['category']; 
     $newsletter = $_POST['newsletter']; 
     $response = $_POST['response']; 
     $reason = $_POST['reason']; 
     $ip = $_POST['ip']; 
     $useragent = $_POST['useragent']; 
     $attempt = $_POST['attempt']; 
     $status = $_POST['status']; 
     $type = $_POST['type']; 
     $url = $_POST['url']; 
     $additional_arguments = $_POST['additional_arguements']; 
     $event_post_timestamp = $_POST['event_post_timestamp']; 
     $raw = $_POST['raw']; 
     $customer_id = $_POST['customer_id']; 

     insert("sendgrid_events", array("uid" => $uid, 
      "timestamp" => $timestamp, 
      "event" => $event_type, 
      "email" => $email_address, 
      "smtpid" => $smtpid, 
      "sg_event_id" => $sg_event_id, 
      "sg_message_id" => $sg_message_id, 
      "category" => $category, 
      "newsletter" => $newsletter, 
      "response" => $response, 
      "reason" => $reason, 
      "ip" => $ip, 
      "useragent" => $useragent, 
      "attempt" => $attempt, 
      "status" => $status, 
      "type" => $type, 
      "url" => $url, 
      "additional_arguments" => $additional_arguments, 
      "event_post_timestamp" => $event_post_timestamp, 
      "raw" => $raw, 
      "customer_id" => $customer_id)); //Unique Arguement to attach customer id on original outbound email? Yes 
    } 

還是非常新的PHP,所以感謝您的幫助。

作爲對響應的迴應:是在json_decode函數處理後以數組形式從sendgid發佈的數據?我仍然不確定我做錯了什麼。我已經修改了我的代碼下面,我讓我的所有變量未定義指數的foreach和在foreach本身無效arguement外...

<?php 

require_once('../functions.php'); 
connect(); 

    $data = file_get_contents("php://input"); // Can i do this? Or do i just pass a $json variable? 
    $records = json_decode($data, true); 

    $uid = $_POST['uid']; 
    $timestamp = $_POST['timestamp']; 
    $event_type = $_POST['event']; 
    $email_address = $_POST['email']; 
    $smtpid = $_POST['smtpid']; 
    $sg_event_id = $_POST['sg_event_id']; 
    $sg_message_id = $_POST['sg_message_id']; 
    $category = $_POST['category']; 
    $newsletter = $_POST['newsletter']; 
    $response = $_POST['response']; 
    $reason = $_POST['reason']; 
    $ip = $_POST['ip']; 
    $useragent = $_POST['useragent']; 
    $attempt = $_POST['attempt']; 
    $status = $_POST['status']; 
    $type = $_POST['type']; 
    $url = $_POST['url']; 
    $additional_arguments = $_POST['additional_arguments']; 
    $event_post_timestamp = $_POST['event_post_timestamp']; 
    $raw = $_POST['raw']; 
    $customer_id = $_POST['customer_id']; 

    foreach ($records as $record) { 

     insert("sendgrid_events", array("uid" => $uid, 
             "timestamp" => $timestamp, 
             "event" => $event_type, 
             "email" => $email_address, 
             "smtpid" => $smtpid, 
             "sg_event_id" => $sg_event_id, 
             "sg_message_id" => $sg_message_id, 
             "category" => $category, 
             "newsletter" => $newsletter, 
             "response" => $response, 
             "reason" => $reason, 
             "ip" => $ip, 
             "useragent" => $useragent, 
             "attempt" => $attempt, 
             "status" => $status, 
             "type" => $type, 
             "url" => $url, 
             "additional_arguments" => $additional_arguments, 
             "event_post_timestamp" => $event_post_timestamp, 
             "raw" => $raw, 
             "customer_id" => $customer_id)); //Unique Arguement to attach customer id on original outbound email? Yes 
    } 

    echo "POST Received"; 
+0

你是否在這個腳本的開始處開始php會話?即'session_start();'? – Latheesan 2014-10-03 16:33:43

+0

對不起,我沒有包括那部分。我會編輯。 – GRANDLarsony 2014-10-03 16:39:48

回答

1

看起來你可能誤解了如何Event Webhook。每次發生事件時(例如,某人打開您的電子郵件),Webhook將POST的數據發送到您的端點(在這種情況下,您的PHP腳本)。這一切都是實時發生的。它您希望用來獲取和存儲事件的API。

但是,您的腳本也使用App/Filter Activation Endpoint。此端點打開和關閉使用過濾器(也稱爲應用程序)。您只需要使用一次,以確保在發生事件時將數據發佈到PHP腳本。然而,通過SendGrid's Web Interface來激活它可能更容易。有關應用程序的更多信息以及您可以使用和修改的方法可以在app description page上找到。

如果您從腳本中刪除cURL請求位,您只需從POST請求中獲取數據並將其存儲起來。通過改變你的腳本如下,事情應該工作:

<?php 

// All your boilerplate code 
require_once('../functions.php'); 
connect(); 

// Get the raw POSTed data 
$data = file_get_contents("php://input"); 

// Decode said data 
$records = json_decode($data, true); 

// Loop through the records 
foreach ($records as $record) { 
    // Store the event 
    // Assume store_event does your data processing and inserting 
    store_event($record); 

    // You should be able to access any parameter of the event as so 
    // $record["email"]; 
    // e.g. 

    echo $record["email"]; 
    echo " had an email "; 
    echo $record["event"]; 
} 

你的錯誤是在下面的行,在那裏你試圖給我們的輸入POST版給您的API響應的關鍵,當你設置過濾器。由於它不存在,因此數據未定義,因此無法用foreach進行迭代。

// The "bad" code 
$data = $response[file_get_contents("php://input")]; 

您可以看到一個working code example of the event webhook on SendGrid's Documentation

+0

感謝您的洞察力,我想我現在對數據如何發佈到我的端點有了更好的理解,接受了我現有的捲曲代碼的需求,但是我不需要我的終端上使用sendgrid憑據進行某種身份驗證?除了身份驗證之外,我已經修改了上面的代碼。 – GRANDLarsony 2014-10-06 16:04:11

+0

當您向SendGrid發送您希望將數據發佈到的URL時,您已經獲得「授權」,您無需再次使用SendGrid進行身份驗證(當我們向您發佈數據時)。如果您確實希望確保SendGrid是爲您提供數據的方法,那麼在此答案中詳細介紹添加身份驗證的方法:http://stackoverflow.com/a/20865822/648494 – 2014-10-07 16:33:04