Sending LINE Messages
Reply API and Push API
Due to cost concerns, you should clearly understand before sending any messages is the difference between Reply API and Push API:
Reply API is free. However, your bot can only reply to the user once after a user interacts with your LINE official account. For each bot reply, you can send up to 5 message objects (See LINE's official document, Sending Reply Messages). If you attempt to reply with more than 5 message objects, you may see an error in your console.
Push API allows developers to send messages directly to users anytime. However, it might cost some money depends on the pricing plan in your country.
By default, Bottender uses Reply API to send messages to users in conversations.
Note: Reply API only works within 30 seconds from a user interacts with your LINE official account.
Batching Messages
By default, Bottender runs in Batch Mode. Messages to reply are put into the queue and sent to LINE in a single request.
To send "hello" and "world" with two messages, you can use one of the following usage:
- Call
context.sendText()
two times:
await context.sendText('hello');
await context.sendText('world');
- Call
send()
with two message objects:
await context.send([
{
type: 'text',
text: 'hello',
},
{
type: 'text',
text: 'world',
},
]);
The above two examples are equivalent. However, we recommend using the first usage because of better compatibility with other platforms.
Sending Text Messages
Text message is the most frequent and common message types among all chat channels. It also offers a minimal format while carrying out dynamic data, e.g., stock price and weather info.
Plain Text
The following example shows how to reply with plain text.
async function SendHi(context) {
await context.sendText('Hi!');
}
For more information, please refer to LINE's official doc, Text Message.
Text with LINE emoji
You can include LINE's original emoji (usually involves LINE Friends) in text messages using character code. You can find the list of LINE emoji in emoji list.
async function SendHi(context) {
await context.sendText(`${String.fromCodePoint(0x100084)} Hi!`);
}
Sending Rich Media Messages
Rich Media Messages of LINE consist of stickers, images, videos, audios, locations, and imagemaps. Rich Media Messages is useful when your priority is to catch the user's attention, e.g., limited promotion. Plus, it is also handy to create an immersive experience, e.g., telling a story.
Sticker
By Stickers, LINE creates a versatile, communicative language. Stickers make your bot expressive and engaging. To send a sticker, you need to indicate the package ID and sticker ID of the sticker.
await context.sendSticker({
packageId: '1',
stickerId: '1',
});
For more information, please refer to LINE's official doc, Sticker Message.
Note: You can only send LINE's original Stickers. You can find the sticker's package ID and sticker ID in the sticker list.
Image
To send an Image, you need to prepare URLs of the original image and a smaller preview image. Users can see the preview image in the chat. When the user clicked the preview image, s/he can see the original image.
If you want to set up a call to action on the image, you may refer to Imagemaps.
await context.sendImage({
originalContentUrl: 'https://example.com/image.jpg',
previewImageUrl: 'https://example.com/preview.jpg',
});
For more information, please refer to LINE's official doc, Image Message.
Note: The URLs must use HTTPS over TLS 1.2 or later.
Video
To send a Video, you need to prepare the URL of the video file and the URL of a preview image. The user can play the video by tapping on the preview image.
await context.sendVideo({
originalContentUrl: 'https://example.com/video.mp4',
previewImageUrl: 'https://example.com/preview.jpg',
});
For more information, please refer to LINE's official doc, Video Message.
Note: The URLs must use HTTPS over TLS 1.2 or later.
Audio
To send an Audio
file, you need to prepare the URL of the file and the duration of the audio.
await context.sendAudio({
originalContentUrl: 'https://example.com/audio.mp3',
duration: 240000,
});
For more information, please refer to LINE's official doc, Audio Message.
Note: The URLs must use HTTPS over TLS 1.2 or later.
Location
To send your location information to users, you have to prepare a title, address, and latitude and longitude.
await context.sendLocation({
title: 'my location',
address: '〒150-0002 東京都渋谷区渋谷2丁目21−1',
latitude: 35.65910807942215,
longitude: 139.70372892916203,
});
For more information, please refer to LINE's official doc, Location Message.
Imagemap
Imagemap offers very flexible and interactive usage. It is an image with multiple tappable areas. When a user taps one of these areas, the user can link to a webpage or send a message on their behalf.
const imagemap = {
baseUrl: 'https://example.com/bot/images/rm001',
baseSize: {
height: 1040,
width: 1040,
},
actions: [
{
type: 'uri',
linkUri: 'https://example.com/',
area: {
x: 0,
y: 0,
width: 520,
height: 1040,
},
},
{
type: 'message',
text: 'hello',
area: {
x: 520,
y: 0,
width: 520,
height: 1040,
},
},
],
};
const altText = 'this is an imagemap';
await context.sendImagemap(altText, imagemap);
For more information, please refer to LINE's official doc, Imagemap Message.
Sending Template Messages
Template message is interactive gallery composed of image, video, title, subtitle, and buttons.
Template message is the key to offer rich media interaction. It is usually used in the scenario of display multiple choices and next actions to the user, e.g., applying coupons, booking a room, making a reservation.
Note: Compared with Template Message, we highly depend on Flex Message once it is available. There are two main reasons:
- Flex Message supports both desktop and mobile devices, while Template Message only supports mobile devices.
- Flex Message is an HTML-like chat UI, which creates a better, engaging user experience.
const template = {
type: 'buttons',
thumbnailImageUrl: 'https://example.com/bot/images/image.jpg',
title: 'Menu',
text: 'Please select',
actions: [
{
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=123',
},
{
type: 'postback',
label: 'Add to cart',
data: 'action=add&itemid=123',
},
{
type: 'uri',
label: 'View detail',
uri: 'http://example.com/page/123',
},
],
};
const altText = 'this is a template';
await context.sendTemplate(altText, template);
Confirm Template
A Confirm Template is designed for confirmation.
const template = {
text: 'Are you sure?',
actions: [
{
type: 'message',
label: 'Yes',
text: 'yes',
},
{
type: 'message',
label: 'No',
text: 'no',
},
],
};
const altText = 'this is a confirm template';
await context.sendConfirmTemplate(altText, template);
For more information, please refer to LINE's official doc, Confirm Template.
Buttons Template
A Buttons Template
includes an image, title, text, and multiple action buttons.
const template = {
thumbnailImageUrl: 'https://example.com/bot/images/image.jpg',
title: 'Menu',
text: 'Please select',
actions: [
{
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=123',
},
{
type: 'postback',
label: 'Add to cart',
data: 'action=add&itemid=123',
},
{
type: 'uri',
label: 'View detail',
uri: 'http://example.com/page/123',
},
],
};
const altText = 'this is a button template';
await context.sendButtonTemplate(altText, template);
For more information, please refer to LINE's official doc, Buttons Template.
Note: Depending on the character width, the message text may not fully be displayed due to the height limitation of the text area.
Carousel Template
Carousel Template is an upgraded version of Buttons Template. For each Buttons Template, you can have an image, title, text, and multiple action buttons.
You can have up to 10 Buttons Template in a row to compose a Carousel Template.
const template = [
{
thumbnailImageUrl: 'https://example.com/bot/images/item1.jpg',
title: 'this is menu',
text: 'description',
actions: [
{
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=111',
},
{
type: 'postback',
label: 'Add to cart',
data: 'action=add&itemid=111',
},
{
type: 'uri',
label: 'View detail',
uri: 'http://example.com/page/111',
},
],
},
{
thumbnailImageUrl: 'https://example.com/bot/images/item2.jpg',
title: 'this is menu',
text: 'description',
actions: [
{
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=222',
},
{
type: 'postback',
label: 'Add to cart',
data: 'action=add&itemid=222',
},
{
type: 'uri',
label: 'View detail',
uri: 'http://example.com/page/222',
},
],
},
];
const altText = 'this is a carousel template';
await context.sendCarouselTemplate(altText, template);
For more information, please refer to LINE's official doc, Carousel Template.
Note:
- Depending on the character width, the message text may not fully be displayed due to the height limitation of the text area.
- You have to keep the number of actions consistent for all columns.
Image Carousel Template
Image Carousel Template has multiple images that can be cycled like a carousel. Users can scroll the images horizontally to browse possible choices. Without the bother of buttons, it helps your user focus on the product images.
const template = [
{
imageUrl: 'https://example.com/bot/images/item1.jpg',
action: {
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=111',
},
},
{
imageUrl: 'https://example.com/bot/images/item2.jpg',
action: {
type: 'message',
label: 'Yes',
text: 'yes',
},
},
{
imageUrl: 'https://example.com/bot/images/item3.jpg',
action: {
type: 'uri',
label: 'View detail',
uri: 'http://example.com/page/222',
},
},
];
const altText = 'this is a image carousel template';
await context.sendImageCarouselTemplate(altText, template);
For more information, please refer to LINE's official doc, Image Carousel Template.
Sending Flex Messages
Since we love Flex Message and inspired by its flexibility and interactive, we wrote a separate doc, Flex Message.
Sending with Quick Replies
We would recommend you to treat Quick Reply as an alternative to user text input.
When a user receives a message that contains Quick Reply Buttons from a LINE official account, those buttons appear at the bottom of the chat screen. The user can tap one of the buttons as a reply.
A Quick Reply consists of up to 13 Quick Reply Buttons. When the user taps a Quick Reply Button, the Quick Reply dismissed. Then, the title of the tapped button posts to the conversation as a response. Meanwhile, the user triggers the action bound with the Quick Reply Button.
Quick Reply can be used in a 1 on 1 chat with a LINE official account, a group, and a room.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'cameraRoll',
label: 'Send photo',
},
},
{
type: 'action',
action: {
type: 'camera',
label: 'Open camera',
},
},
],
};
For more information, please refer to LINE's official doc, Using Quick Reply.
Sending Quick Reply
Since Quick Reply works as an alternative of user input, you have to send Quick Reply as an attachment of other messages, e.g., Text Message, Template Message, or Flex.
Sending Quick Reply with Message
await context.send([
{
type: 'text',
text: 'hello',
quickReply,
},
]);
Sending Quick Reply with Text Message
await context.sendText('hello', { quickReply });
Sending Quick Reply with Template Message
await context.sendTemplate(altText, template, { quickReply });
Sending Quick Reply with Buttons Template Message
await context.sendButtonTemplate(altText, template, { quickReply });
Sending Quick Reply with Confirm Template Message
await context.sendConfirmTemplate(altText, template, { quickReply });
Sending Quick Reply with Carousel Template Message
await context.sendCarouselTemplate(altText, template, { quickReply });
Sending Quick Reply with Flex Message
await context.sendFlex(altText, contents, { quickReply });
In the following sections, you can see various types of Quick Reply.
Text Quick Reply
When this action is tapped, the string in the text property is sent as a message from the user.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'message',
label: 'Yes',
text: 'Yes',
},
},
],
};
For more information, please refer to LINE's official doc, Message Actions.
Postback Quick Replay
When the action is tapped, a postback event is returned via webhook with the specified string in the data property.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'postback',
label: 'Buy',
data: 'action=buy&itemid=111',
text: 'Buy',
},
},
],
};
For more information, please refer to LINE's official doc, Postback Actions.
URI Quick Reply
The URI opened when the action is performed. The available schemes for URI are http
, https
, line
, and tel
. For the LINE URL scheme, you can trigger the following actions:
- Opening the camera and camera roll
- Opening the location screen
- Sharing your LINE official account
- Opening your LINE official account's Timeline and account page
- Sending text messages
- Opening profile information
- Opening common LINE screens
- Opening LINE settings screens
- Opening the Sticker Shop
- Opening the Theme Shop
- Making phone calls with LINE Out
- Opening a LIFF app
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'uri',
label: 'View details',
uri: 'http://example.com/page/222',
altUri: {
desktop: 'http://example.com/pc/page/222',
},
},
},
],
};
For more information, please refer to LINE's official doc, URI Actions.
Note:
- The
altUri.desktop
property is supported only when you set URI actions in Flex Messages.- For more information about the LINE URL scheme, see Using the LINE URL Scheme.
Datetime Picker Quick Reply
When a control associated with this action is tapped, a postback event is returned via webhook with the date and time selected by the user from the date and time selection dialog. The Datetime Picker
action does not support time zones.
There are three different modes:
- date: Pick a date
- time: Pick time
- datetime: Pick date and time
const quickReply = {
items: [
{
type: 'datetimepicker',
label: 'Select date',
data: 'storeId=12345',
mode: 'datetime',
initial: '2017-12-25t00:00',
max: '2018-01-24t23:59',
min: '2017-12-25t00:00',
},
],
};
For more information, please refer to LINE's official doc, Datatime Picker Actions.
Note: The datetime picker action is only supported on versions equal to or later than LINE 7.9.0 for iOS and LINE 7.12.0 for Android.
Camera Quick Reply
This action can be configured only with quick reply buttons. When a button associated with this action is tapped, the camera screen in LINE is opened.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'camera',
label: 'Camera',
},
},
],
};
For more information, please refer to LINE's official doc, Camera Actions.
Camera Roll Quick Reply
This action can be configured only with quick reply buttons. When a button associated with this action is tapped, the camera roll screen in LINE is opened.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'cameraRoll',
label: 'Camera roll',
},
},
],
};
For more information, please refer to LINE's official doc, Camera Roll Actions.
Location Quick Reply
This action can be configured only with quick reply buttons. When a button associated with this action is tapped, the location screen in LINE is opened.
const quickReply = {
items: [
{
type: 'action',
action: {
type: 'location',
label: 'Location',
},
},
],
};
For more information, please refer to LINE's official doc, Location Action.
Sending Messages with Icon and Display Name
You can specify the icon and display name by providing the sender
property in the message options:
const sender = {
name: 'Cony',
iconUrl: 'https://line.me/conyprof',
};
await context.sendText('Hello, I am Cony!!', { sender });
await context.sendImage(
{
originalContentUrl: 'https://example.com/image.jpg',
previewImageUrl: 'https://example.com/preview.jpg',
},
{ sender }
);
If you prefer to send messages with LINE original message objects, you can provide the sender
property in the message object:
await context.send([
{
type: 'text',
text: 'Hello, I am Cony!!',
sender: {
name: 'Cony',
iconUrl: 'https://line.me/conyprof',
},
},
]);
For more info, refer to LINE's official doc, Change icon and display name.
Rate Limits
Just like many chat channels, LINE has rate limits for each endpoint. If you continue to send requests exceeding the rate limit for an extended period, your bot might stop responding. It is because LINE blocks incoming requests to your bot.
You have to take care Rate Limits if you attempt to build a campaign bot with massive sudden traffic, e.g., super discount for Black Friday.
Send API
For Send API, you have to follow the below Rate Limits:
- 100,000 requests per minute
- 1,700 requests per second
For more information, please refer to LINE's API doc, Rate Limits