How to Use LIFF with LINEJS: Complete Integration Guide

LINEJS provides a built-in LiffService that automates LIFF token issuance, consent handling, and message sending through the client.liff API, requiring only a logged-in BaseClient instance to execute LIFF operations.

The LINE Frontend Framework (LIFF) enables web applications to integrate with the LINE messaging platform and access user context. LINEJS, an open-source TypeScript library for LINE automation, abstracts the complex LIFF protocol through its LiffService class. This guide demonstrates how to use LIFF with LINEJS to issue access tokens, handle user consent flows, and send messages without managing low-level Thrift encoding manually.

Architecture of LIFF Integration in LINEJS

LINEJS implements LIFF support through a layered architecture centered on the BaseClient class. When you instantiate a client, it automatically creates a LiffService instance exposed as client.liff.

Core Components

  • BaseClient – The central entry point defined in packages/linejs/base/core/mod.ts that initializes LiffService and exposes it as client.liff. It handles authentication, storage, and request routing.
  • LiffService – The primary implementation located in packages/linejs/base/service/liff/mod.ts that provides issueLiffView, getLiffToken, sendLiff, and consent helpers (tryConsentLiff, tryConsentAuthorize).
  • LINETypes – TypeScript definitions for LIFF structures such as LiffViewResponse stored in packages/types/line_types.ts.
  • RequestClient – Low-level Thrift request wrapper in packages/linejs/request/mod.ts used internally by LiffService to communicate with LINE's backend.

LIFF Token Flow

When you call client.liff.getLiffToken(), the service executes this workflow:

  1. Issue LIFF View – Calls issueLiffView to request a short-lived access token for the specified user or chat.
  2. Consent Handling – If the server returns CONSENT_REQUIRED, the service automatically executes tryConsentLiff (in-app flow) or tryConsentAuthorize (web flow) to obtain user approval without manual intervention.
  3. Token Retrieval – Extracts the accessToken from the LiffViewResponse and caches it for subsequent operations.

Step-by-Step: Using LIFF with LINEJS

Follow these steps to integrate LIFF functionality into your LINEJS application:

  1. Initialize BaseClient – Create a client instance with your preferred device type (iOS, Android, Desktop, etc.).
  2. Authenticate – Log in using email/password, QR code, or OAuth token to establish a valid session.
  3. Configure LIFF ID – Optionally override the default LIFF ID (2006747340-AoraPvdD) with your registered application ID.
  4. Obtain LIFF Token – Call client.liff.getLiffToken() with the target chat MID to retrieve an access token.
  5. Send Messages – Use client.liff.sendLiff() to post messages to the target conversation using the obtained token.

Complete Code Example

The following example demonstrates a full LIFF workflow from initialization to message delivery:

import { BaseClient } from "@evex/linejs";

// 1️⃣ Initialise the client (device must be one of the supported strings)
const client = new BaseClient({
  device: "iOS",            // or "Android", "DESKTOP", …
  version: "15.0",          // optional device version
});

// 2️⃣ Perform login (example: email/password)
await client.loginProcess.login({
  email: "you@example.com",
  password: "yourPassword",
});

// 3️⃣ Obtain a LIFF token for a specific chat (or user MID)
const liffToken = await client.liff.getLiffToken({
  chatMid: "u1234567890abcdef", // target user MID (optional)
  liffId: "2006747340-AoraPvdD", // replace with your own LIFF ID if needed
});

// 4️⃣ Send a simple text message via LIFF
await client.liff.sendLiff({
  to: "u1234567890abcdef", // same MID as above
  messages: [{ type: "text", text: "Hello from LINE JS + LIFF!" }],
});

Implementation Breakdown

Line Component Description
new BaseClient(...) BaseClient Instantiates the core client, which creates client.liff automatically.
loginProcess.login(...) Auth Authenticates the session and sets client.authToken.
client.liff.getLiffToken(...) LiffService Calls issueLiffView internally; handles consent automatically if required.
client.liff.sendLiff(...) LiffService Posts the message array to https://api.line.me/message/v3/share using the retrieved token.

Note – If issueLiffView returns a CONSENT_REQUIRED error, the LiffService automatically executes tryConsentLiff (in‑app flow) or tryConsentAuthorize (web flow) and retries the token request without manual intervention.

Advanced LIFF Operations

Custom LIFF ID Configuration

While LINEJS uses a default LIFF ID (2006747340-AoraPvdD), production applications should register their own LIFF app in the LINE Developers Console and override this default:

const customId = "12345678-YourCustomId";
await client.liff.getLiffToken({
  chatMid: "u1234567890abcdef",
  liffId: customId,
});

The LiffService in packages/linejs/base/service/liff/mod.ts implements two consent strategies:

  • In‑app consent (tryConsentLiff): Posts to https://access.line.me/dialog/api/permissions with the channel ID and current LINE access token. This flow executes when the client runs on desktop or mobile environments with direct API access.
  • Web consent (tryConsentAuthorize): Fetches the consent page, extracts the CSRF token using the regex /<input type="hidden" name="__csrf"…/, then POSTs the permission grant to https://access.line.me/oauth2/v2.1/authorize/consent.

Both methods return a boolean indicating success; getLiffToken automatically retries the LIFF view request upon successful consent.

Token Caching Strategy

LiffService maintains an internal liffTokenCache object that stores access tokens mapped by target MID to avoid redundant issueLiffView calls. To bypass caching and force a fresh token issuance—useful when permissions change or tokens expire prematurely—set the forceIssue: true option:

await client.liff.sendLiff({
  to: "u1234567890abcdef",
  messages: [{ type: "text", text: "Forced refresh" }],
  forceIssue: true,
});

Summary

  • LINEJS exposes LIFF functionality through the client.liff API, which is an instance of LiffService created automatically by BaseClient during initialization in packages/linejs/base/core/mod.ts.
  • The getLiffToken method handles the complete LIFF lifecycle: issuing views via issueLiffView, processing consent via tryConsentLiff or tryConsentAuthorize, and retrieving access tokens.
  • Source files for LIFF operations are located in packages/linejs/base/service/liff/mod.ts (service logic) and packages/linejs/base/core/mod.ts (client initialization).
  • Token caching is automatic, but you can force fresh issuance with forceIssue: true when calling sendLiff.
  • All network communication uses the internal RequestClient (Thrift-based) and standard HTTP POSTs to LINE's messaging endpoints.

Frequently Asked Questions

You typically do not need to handle consent manually. The LiffService in packages/linejs/base/service/liff/mod.ts automatically detects CONSENT_REQUIRED errors from issueLiffView and executes either tryConsentLiff (in-app flow) or tryConsentAuthorize (web flow) before retrying the token request. If you need to disable automatic consent or implement a custom flow, you would need to extend the LiffService class and override the consent methods.

What is the default LIFF ID in LINEJS and should I change it?

The default LIFF ID used by LINEJS is 2006747340-AoraPvdD, defined in the LiffService implementation. For production applications, you should register your own LIFF application in the LINE Developers Console and override this default by passing your custom liffId parameter to getLiffToken or sendLiff methods. Using your own LIFF ID ensures proper branding and permission scopes for your specific use case.

How does LINEJS cache LIFF tokens and when should I force a refresh?

LiffService maintains an internal liffTokenCache object that stores access tokens mapped by target MID to avoid redundant issueLiffView calls. Tokens are reused for subsequent sendLiff operations until they expire or the process restarts. To bypass caching and force a fresh token issuance—useful when permissions change or tokens expire prematurely—set the forceIssue: true option in your sendLiff or getLiffToken method calls.

Can I use LINEJS LIFF features without logging in?

No, LIFF operations require an authenticated session because LiffService relies on the authToken and device information stored in BaseClient to sign Thrift requests to LINE's backend. The issueLiffView method specifically requires valid authentication credentials to generate access tokens for specific users or chats. You must complete the login process via client.loginProcess.login() before invoking any client.liff methods.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →