Facebooks’ Lead Generation Form integration with your CRM or any other Client Application

Eyas Mattar
5 min readMay 6, 2019

--

This story will guide you all the way to create a direct pipeline from Facebooks’ Lead Generation forms to a given CRM app or any other client application for your request using Spring Boot server, PostgreSQL and AWS EC2.

Warning

This story is NOT about:

Creating Facebook ads

Creating Facebook App

Marketing

Webhosting

Prerequisites

  1. Facebook Developers account
  2. Active Facebook Business Account
  3. Active Facebook Page that is associated with the Business Account to run the Ads on
  4. Webserver hosting with SSL and HTTPS protocol

Creating a Facebook App

  1. Goto https://developers.facebook.com and Create a new App

2. Goto Setting-> Basic and Provide all information about this App, make sure you provide all the information requested and a valid information, because Facebook will review your App and Approve it before it goes LIVE.

3. Turn on the App by clicking the icon on Top Middle of the page

4. Wait until Facebook approve your App.

Creating our RESTful Spring Boot server

  1. Goto https://start.spring.io/ and get a SpringBoot starter project

2. Import the starter in your favorite IDE, mine is IntelliJ

3. Goto your application.properties and provide your Database connection information. I am using PostgreSQL

spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?currentSchema=leadsdb
spring.datasource.username=
spring.datasource.password=
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

spring.jpa.hibernate.ddl-auto = create-drop
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
spring.jpa.show-sql = true

Make sure to change spring.jpa.hibernate.ddl-auto = create-drop to spring.jpa.hibernate.ddl-auto = update after the first run

4. Create a Lead @Entity

@Entity
@Table(name = "lead")
public class Lead implements Serializable {

private static final long serialVersionUID = -3009157732242241606L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@NotNull
@Size(min=3, message="First Name: minimum 4 characters")
@Pattern(regexp="^[A-Za-z]+", message="First Name: Illegal characters")
@Column(name = "firstname")
private String firstName;

@NotNull
@Size(min=3, message="Last Name: minimum 4 characters")
@Pattern(regexp="^[A-Za-z]+", message="Last Name: Illegal characters")
@Column(name = "lastname")
private String lastName;

@NumberFormat(style = NumberFormat.Style.NUMBER)
@Column(name = "phonenumber")
private String phoneNumber;

@NotNull
@Pattern(regexp="[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?",
message="Email: Illegal email")
@Column(name = "email")
private String email;

public Lead(
String firstName,
String lastName,
String phoneNumber,
String email) {
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
this.email = email;
}

public static long getSerialVersionUID() {
return serialVersionUID;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getPhoneNumber() {
return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}
}

5. Create a CrudRepository for the Lead Entity

@Repository
public interface LeadRepo extends CrudRepository<Lead, String> {

}

6. Create a controller to consume the Facebook webhook requests

@PostMapping(value = "/lead")
public GeneralResponse addLead(@RequestBody Object req) {
try {
String result = this.mainService.addLead(req);
return new GeneralResponse<String, String>(result,successPreceding);
} catch (Exception e) {
return new GeneralResponse<String, String>(null, errorPreceding + e.getMessage());
}
}

7. Create a Service to Parse the request body and extract the Lead information

When a Lead is generated, the Webhook sends a POST request with a “notification”, telling the Endpoint that a new Lead has been generated, so we should obtain the lead_id from the “notification” so we can afterwards, request the Lead information from Facebook Graph API

@Override
public String addLead(Object req) {
if (req != null) {
try {
String leadgen_id = ((LinkedHashMap)((LinkedHashMap)((ArrayList)(((LinkedHashMap)(((ArrayList)(((LinkedHashMap)(((LinkedHashMap) req)
.get("body")))
.get("entry")))
.get(0))).get("changes")))
.get(0)).get("value")).get("leadgen_id").toString();
Lead newLead = this.getLeadInformation(leadgen_id);
leadRepo.save(newLead);
} catch(Exception e ) {
return e.getMessage();
}
}
return "Wrong lead request";
}

The above function/method gets the leadgen_id from the request and passes to the getLeadInformation(leadgen_id)

private Lead getLeadInformation(String id) {
String accessToken = "tokenDSSALDMnbsadadgFDvMpUI";
RestTemplate restTemplate = new RestTemplate();
String facebookGrapUrl
= "https://graph.facebook.com/v2.10/"+id
+ "?access_token="+accessToken;
ResponseEntity<String> response
= restTemplate.getForEntity(facebookGrapUrl, String.class);
Lead newLead = new Lead();
.....
...Parsing the lead info from the JSON string response
......
return newLead;
}

You can add a function/method to POST the Lead to a CRM Application,

but I will skip this step, because it is trivial and unnecessary for this tutorial.

8. When creating our App in Facebook, Facebook requires the endpoint URL to where the Webhook will send the “notification”, with the endpoint URL we should provide a custom “token” that will be send in the Verification request body.

When entering the endpoint URL in the APP, Facebook will send a verification request to the URL that we supplied with GET method, let’s now create a GET Controller to accept the verification from Facebook.

@GetMapping(value = "/lead")
public GeneralResponse verifyLead(@RequestBody Object req) {
try {
String token = ((LinkedHashMap)(((LinkedHashMap) req).get("query"))).get("hub.verify_token").toString();
String challenge = ((LinkedHashMap)(((LinkedHashMap) req).get("query"))).get("hub.challenge").toString();
if (token == "mytoken") {
return new GeneralResponse<String, String>(challenge,successPreceding);
} else {
return new GeneralResponse<String, String>("Error",successPreceding);
}
} catch (Exception e) {
return new GeneralResponse<String, String>(null, errorPreceding + e.getMessage());
}
}

“mytoken” is the verification token that we provided in the Facebook App.

9. After finishing our RESTful service we Package the server as .jar or .war, preferable JAR.

10. Deploy the JAR on your webserver hosting and run it, I use Amazon EC2 ubuntu machine with 20GB storage and Amazon PostgreSQL service. To deploy .jar on ubuntu you can read this article

Going back the Faceboook App

  1. Goto your AWS instance information, where your ubuntu machine were set, and get the HOSTNAME/IP of the machine.

make sure TCP with the PORT of your server is OPEN in the instance settings, so your machine can accept incoming requests and pass to your server.

2. Go back to the Facebook App were we stopped in steps earlier, and click on

and then click on “Subscribe to this object”

fill in the Endpoint URL and the Verify Token “mytoken”

Please note that the endpoint URL should include HTTPS

Click on Verify and Save

2. After subscribing successfully to the Page

Subscribe to leadgen, so you can get notification on Lead Generation

Thats it, you can now test the Webhooks on https://developers.facebook.com/tools/lead-ads-testing

--

--

Responses (1)