As of October 1, 2023, LINE has been rebranded as LY Corporation. Visit the new blog of LY Corporation here: LY Corporation Tech Blog

Blog


The Road to Releasing LINE Trial Bot SDK

Introduction

Hello, my name is Matsuno and I work at LINE.

LINE BOT API Trial accounts were announced a few days ago, receiving a warm welcome from developers all over the world. Previously only available to developers working at companies who were under contract with LINE, now any individual developer can freely start developing their own project with their own LINE bot account.
In this post, I would like to talk about why we decided to start development on a LINE BOT API Trial account SDK and how we released it in less than a week.

Why the Bot SDK was created

As soon as LINE BOT API Trial accounts were announced, many of our own LINE engineers started developing for them. Which is when we began thinking...
What's the most difficult part about creating a bot with this API??

Especially for static languages like Java, you need to create individual classes to map JSONs to. You have to implement a number of classes for things such as text messages, video chat, stickers, rich messages because in the case of LINE BOT API Trial accounts, there are many messages that send and receive API endpoints such as the ones mentioned above. Creating classes for each and every table available on LINE Developers is a painstaking endeavor and this prompted us to think,
this is actually a big deal!

We learned through several sources, mainly through company chats, that many people thought the same way.

That is how we came to the conclusion that:

If we want more people using LINE BOT API Trial accounts, we have to release an SDK!!!

Now that we realized what we needed, we had to get to actually gathering our engineers and writing an SDK for each language. The languages were selected based on their general popularity in the community and among the engineers inside the company. Java and Perl were selected as the main languages and a handful of volunteers were assigned to handling Ruby and PHP. There were also suggestions to develop one for the static language Go, so some were assigned to that project.

Once we were on the initiative, we quickly made progress and had working SDKs for each language in about a week.

The following were taken into consideration when creating the SDK.

  • Organizing API method names for each language
    • Users are frustrated when the interface is vastly different with each language.
  • Gathering the experts for each language
    • In order to ensure that the rules and standards of each language community are followed, we assigned engineers that had prior experience of releasing projects to those language module repositories.
  • Performing thorough reviews to guarantee quality
    • We configured a "lint" for each language, so that we could ensure a certain amount of quality.
  • Performing security checks
    • We minimized module dependencies as much as possible.
  • Minimizing module dependencies
    • Having too many module dependencies can raise the learning curve.
    • We avoided using libraries that can globally affect classes once they are loaded, such as Ruby's ActiveSupport.

After all this, we were able to release LINE BOT API Trial accounts. Hurrah!

Trial Bot SDK for Java Configurations

Below, I would like to talk about the configurations of the Java SDK, which I was in charge of.

The SDK supports Java version 8 or above. Since LINE BOT API Trial accounts is a "trial" I figured there would be many cases where environments would be newly created.

For Java, it's common practice to divide modules into smaller parts, and so we did. While there were some concerns regarding how small the parts should be, we eventually reached a conclusion.

line-bot-model

A class for mapping JSON when there is an HTTP request/response.
JSON mapping was implemented under the assumption that Jackson will be used. While both Jackson and Gson are the preferred JSON libraries in the Java community, we chose Jackson because it was the library of choice at LINE.
While we could have created accessors through our IDE for the beans used for mapping, we decided to use lombok instead. Using lombok lets us create Getter/Setters by placing annotations, as you can see below. We were able to create a more easily readable code by using lombok.

Written code Generated code
public class User { @Getter @Setter private String name; } public class User { private String name; public void setName(String name) { this.name = name; } public String getName() { return this.name; } }

If you only intend to use beans configured through lombok for mapping with Jackson, you can do so by adding "@Data" as an annotation to batch create Getter/Setter/equals/hashcode.
A number of LINE web applications already follow this method.
In an SDK however, it's better to set this object to immutable to avoid making people think "There must be a reason why this field has a setter", not to mention improving usability.
So we decided to set objects to immutable and not implement setter methods.
When using immutable classes with Jackson, you must add a @JsonProperty annotation to the constructor's factor so that constructors can create objects. You can see how you can do this below.

@Getter
@ToString
public class EventResponse {
    private final Integer version;
    private final Long timestamp;
    private final String messageId;
    private final int statusCode;
    private final String statusMessage;
    private final List<String> failed;
 
    public EventResponse(
            @JsonProperty("version") Integer version,
            @JsonProperty("timestamp") Long timestamp,
            @JsonProperty("messageId") String messageId,
            @JsonProperty("statusCode") int statusCode,
            @JsonProperty("statusMessage") String statusMessage,
            @JsonProperty("failed") List<String> failed) {
        this.version = version;
        this.timestamp = timestamp;
        this.messageId = messageId;
        this.statusCode = statusCode;
        this.statusMessage = statusMessage;
        this.failed = failed;
    }
}

line-bot-api-client

As an HTTP API client module, this is effectively the "liver" of the SDK.
Apache HttpClient was used for the HTTP client library. Most of the community uses it as well.
However the world of HTTP client libraries are ever fluctuating. We made the interface easy to be adapted to any new trend so that it can be used even when implementing a different HTTP client library.

line-bot-servlet

LINE bot accounts run as web applications.
Since coding web applications on Java requires using servlet by default, servlet compatibility is a necessity.
While some may consider the servlet to be just an outdated API, the servlet API acts as the Rack/WSGI/PSGI of lightweight languages. That's why it's important to incorporate servlet API.
Even if you prepare sample code and SDKs that rely on certain frameworks, it's still important to provide examples of using the servlet so that people who don't know your SDK well can learn it quickly.

line-bot-spring-boot

While it's possible to create your bot on the servlet layer, we also prepared something for those who want to create their bots using a web application framework. This is where Spring Boot comes in.

After configuring dependencies, you can run an echo server by writing code as shown below. As you can see, it's very simple.

package com.example.bot.spring.echo;
 
import com.linecorp.bot.client.LineBotClient;
import com.linecorp.bot.client.exception.LineBotAPIException;
import com.linecorp.bot.model.callback.Message;
import com.linecorp.bot.model.content.Content;
import com.linecorp.bot.model.content.TextContent;
import com.linecorp.bot.spring.boot.annotation.LineBotMessages;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.List;
 
@SpringBootApplication
public class EchoApplication {
    public static void main(String[] args) {
        SpringApplication.run(EchoApplication.class, args);
    }
 
    @RestController
    public static class MyController {
        @Autowired
        private LineBotClient lineBotClient;
 
        @RequestMapping("/callback")
        public void callback(@LineBotMessages List<Message> messages) 
          throws LineBotAPIException {
            for (Message message : messages) {
                Content content = message.getContent();
                if (content instanceof TextContent) {
                    TextContent textContent = (TextContent) content;
                    lineBotClient.sendText(textContent.getFrom(),
                            textContent.getText());
                }
            }
        }
    }
}

sample-spring-boot-echo

An echo bot sample. It can parrot (or "echo") the words you say back to you.
In terms of complexity, this bot is on the simpler side. The SDKs for all languages include sample code for these echo bots in their respective repositories.
We tried to keep the amount of instructions to a minimum so that users could feel that it's easier to implement (The SDK was also designed in a way to reduce instructions as much as possible).

sample-spring-boot-kitchensink

Simple sample code like the echo bot are important to have, but it's also crucial to have sample code that gives a general of idea of what features are available and what they can do.
Through this module, we created a sample that showcases all the features of the SDK. To be more precise, this simply provides implementation for parroting on all events.
This also serves the purpose of testing to see if all features of the SDK are working properly. Following documented instructions is one thing, but the only way to check if something actually works is to test it!

Closing words

LINE BOT API Trial accounts were created through the process above.
GitHub: https://github.com/line

LINE is always looking for more engineers that can join us for SDK development. Server-side engineers【LINE GAME】【Family apps】【LINE Pay】
Server-side engineers【LINE Platform】