Search code examples
phpfacebook-graph-apiherokufacebook-webhooks

Facebook leadgen webhook creating duplicate leads


The Facebook leadgen webhook for my Facebook page is creating two leads for every form submitted on my page.

When using the Facebook leadgen tester the lead is created only once. Have tried this using both filling in the form manually as well as generating a test lead. However when an actual person submits the lead on Facebook, lead is created twice on the CRM. This leads me to believe that Facebook is expecting some sort of a confirmation to notify it that the webhook need not be called again.

Any suggestions on the confirmation message back will be really helpful.

Edit: On further testing, the duplication occurs when the Heroku dyno goes into sleep state and a lead is generated. This causes the webhook to execute but the response from the app to Facebook is failure, this causes the lead to be sent down again and is a success second time around.

Question: How to send a success message in the first instance when the app is set from sleep to awake.

The code that is used on the webhook is as below.

<?php
require_once('./autoload.php');
$input = json_decode(file_get_contents('php://input'),true);
$leadgen_id = $input["entry"][0]["changes"][0]["value"]["leadgen_id"];
$user_access_token = MYTOKEN;

function getLead($leadgen_id,$user_access_token) {
    //fetch lead info from FB API
    $graph_url = 'https://graph.facebook.com/v2.9/' . $leadgen_id. "?access_token=" . $user_access_token;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $graph_url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    $output = curl_exec($ch); 
    curl_close($ch);

    //work with the lead data and pass to an array
    $leaddata = json_decode($output);
    $lead = array();
    for( $i=0; $i<count( $leaddata->field_data ); $i++ ) {
        $lead[$leaddata->field_data[$i]->name]=$leaddata->field_data[$i]->values[0];
        //error_log(print_r($lead, true));
    }
    return $lead;
}

$lead = getLead($leadgen_id,$user_access_token);


//Pass array to CRM specific array
 $queryData = http_build_query(array(
 'fields' => array(
 "TITLE" => $lead['full_name'],
 "STATUS_ID" => "NEW",
 "OPENED" => "Y",
 "ASSIGNED_BY_ID" => 1,
 "PHONE" => array(array("VALUE" => $lead['phone_number'], "VALUE_TYPE" => "WORK" )),
 "EMAIL" => array(array("VALUE" => $lead['email'], "VALUE_TYPE" => "WORK" )),
 "Custom_field_1" => $input["entry"][0]["changes"][0]["value"]["created_time"],
 "Custom_field_2" => $input["entry"][0]["changes"][0]["value"]["page_id"],
 "Custom_field_3" => $input["entry"][0]["changes"][0]["value"]["form_id"],
 "Custom_field_4" => $input["entry"][0]["changes"][0]["value"]["leadgen_id"],
 "Custom_field_5" => "Facebook"
 ),
 'params' => array("REGISTER_SONET_EVENT" => "Y")
 ));


 //Call the CRM JSON
 $queryUrl = 'MYCRM/crm.lead.add.json';


 $curl = curl_init();
 curl_setopt_array($curl, array(
 CURLOPT_SSL_VERIFYPEER => 0,
 CURLOPT_POST => 1,
 CURLOPT_HEADER => 0,
 CURLOPT_RETURNTRANSFER => 1,
 CURLOPT_URL => $queryUrl,
 CURLOPT_POSTFIELDS => $queryData,
 ));

 $result = curl_exec($curl);
 curl_close($curl);
 $result = json_decode($result, 1);

?>

Solution

  • After a reasonable amount of investigation. The issue definitely does not lie with the code, it is to do with the Heroku dynos going into a sleep state every 30 min.

    Temporary solution: use Kaffeine App to keep dynos awake artificially. The issue here is that the dyno hours per month are limited (550 hours). A temporary workaround is to add your payment details to get additional 450 hours.

    Permanent solution: Move to a paid version of Heroku which allows dynos to stay awake all the time.

    The temporary solution works for me as of now as the app has not front end and gets called perhaps 10-15 times a day. The duplicate leads issue needed resolving as the end point can't identify/eliminate duplicates.