2014-10-03 123 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