Facebook posting service

Where does it come from?

As you can read here, I have implemented for JVM Bloggers a mechanism posting on its Facebook page. At first, I started with a microservice idea, running externally from the application. During the work, this concept changed and the posting is a part of the core now.

However, it would be a shame to remove a code of microservice and not to publish it at all. So here it is – a short entry about a microservice publishing on a Facebook page.
 

Mechanics

A source

The service receives messages containing data to be published. A source of them is Kafka – a distributed streaming platform. A connection to it is provided by Reactive Kafka allowing to consume messages in a form of a stream. The service listens on a topic that can be set up in the service’s configuration.

I have created a consumer working in “at-least once” delivery mode. This means when a message is consumed, its offset should be committed to Kafka topic. An interesting exercise would be implementing “Exactly-once” semantic, so a message is read by the service once and only once.
 

Posting a message

I have employed restfb library to connect to the Facebook. It contains com.restfb.DefaultFacebookClient class that provides an API for publishing posts on Facebook pages.

A message is published with the following call:


final FacebookType publishResponse = facebook.publish("me/feed", Post.class, postData.getParams());
You can find more details about required configuration and mechanics of posting on a Facebook page in my earlier post.
 

A message content

The expected format of a message is JSON. It is a map of parameters of a Facebook post. When a message arrives it is parsed into a list of com.restfb.Parameters.

An important note here – I assumed that all fields contained in a Kafka message are well-known to the Facebook protocol. A full list of available parameters can be found here.
 

Failure handling

What about post delivery failures? In a case of any of them, the attempt to post a message will be retried. I have used a Failsafe library to ensure failure handling. The tool provides an easy way to set up a retry policy. For the service the policy and its usage looks like the following:


private final RetryPolicy retryPolicy = new RetryPolicy().withMaxRetries(3).retryOn(Exception.class);
...
Failsafe
.with(retryPolicy)
.onFailedAttempt(ex -> log.error("Sending new post failed.", ex))
.get(() -> facebookPublisher.publishPost(data));
 

Unit testing of the consumer

I wondered how can I test the consumption of messages provided by Reactive Kafka source. The main concern here was setting up Kafka and feeding it with some messages. As you can guess, there is a library for that already, i.e. kafka-junit.

It offers JUnit’s rule that starts a Kafka broker at the beginning of a test and shut it down at its end. With com.github.charithe.kafka.KafkaHelper we can easily produce a message and send it to a specified topic. The library does exactly what I was looking for.
 

How to run

docker-logo The service connects to Kafka on a topic specified in its configuration. Thus, you have to run a Kafka broker at first. The easiest way to do so is to run it from a Docker image. Here is a nice explanation how this can be done.

Next, it is the time to start the posting service. I have added a support of Docker to the project, so you can generate a Docker image and run the service based on it:


docker run -e PAGE_ID=... -e APP_SECRET=... -e ACCESS_TOKEN=... docker_image_id

Of course, you can still do this by simply calling the following from a command line:


java -Dfacebook.app.secret=$APP_SECRET -Dfacebook.user.access.token=$ACCESS_TOKEN -Dfacebook.page.id=$PAGE_ID -Dfacebook.app.id=$APP_ID -jar facebook-posting-service-0.1-all.jar

 

Does it work?

Having both – the Kafka server and the service – running, we can feed the facebook-posting-service topic with a message. To do so, I have used kafka-console-producer.sh and created a JSON message with some text and link.

Sending a test message

What happened next? Here is a part of logs showing that the service posted the message:

A test message consumption

And here is a screenshot from the Facebook page of JVM Bloggers:

A test message published

 

That’s it

The code is on Github. Feel free to use it and let me know how does it work 😉

Leave a Reply