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.tsthat initializesLiffServiceand exposes it asclient.liff. It handles authentication, storage, and request routing. - LiffService – The primary implementation located in
packages/linejs/base/service/liff/mod.tsthat providesissueLiffView,getLiffToken,sendLiff, and consent helpers (tryConsentLiff,tryConsentAuthorize). - LINETypes – TypeScript definitions for LIFF structures such as
LiffViewResponsestored inpackages/types/line_types.ts. - RequestClient – Low-level Thrift request wrapper in
packages/linejs/request/mod.tsused internally byLiffServiceto communicate with LINE's backend.
LIFF Token Flow
When you call client.liff.getLiffToken(), the service executes this workflow:
- Issue LIFF View – Calls
issueLiffViewto request a short-lived access token for the specified user or chat. - Consent Handling – If the server returns
CONSENT_REQUIRED, the service automatically executestryConsentLiff(in-app flow) ortryConsentAuthorize(web flow) to obtain user approval without manual intervention. - Token Retrieval – Extracts the
accessTokenfrom theLiffViewResponseand caches it for subsequent operations.
Step-by-Step: Using LIFF with LINEJS
Follow these steps to integrate LIFF functionality into your LINEJS application:
- Initialize BaseClient – Create a client instance with your preferred device type (iOS, Android, Desktop, etc.).
- Authenticate – Log in using email/password, QR code, or OAuth token to establish a valid session.
- Configure LIFF ID – Optionally override the default LIFF ID (
2006747340-AoraPvdD) with your registered application ID. - Obtain LIFF Token – Call
client.liff.getLiffToken()with the target chat MID to retrieve an access token. - 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
issueLiffViewreturns aCONSENT_REQUIREDerror, theLiffServiceautomatically executestryConsentLiff(in‑app flow) ortryConsentAuthorize(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,
});
Consent Flow Implementation Details
The LiffService in packages/linejs/base/service/liff/mod.ts implements two consent strategies:
- In‑app consent (
tryConsentLiff): Posts tohttps://access.line.me/dialog/api/permissionswith 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 tohttps://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.liffAPI, which is an instance ofLiffServicecreated automatically byBaseClientduring initialization inpackages/linejs/base/core/mod.ts. - The
getLiffTokenmethod handles the complete LIFF lifecycle: issuing views viaissueLiffView, processing consent viatryConsentLiffortryConsentAuthorize, and retrieving access tokens. - Source files for LIFF operations are located in
packages/linejs/base/service/liff/mod.ts(service logic) andpackages/linejs/base/core/mod.ts(client initialization). - Token caching is automatic, but you can force fresh issuance with
forceIssue: truewhen callingsendLiff. - All network communication uses the internal
RequestClient(Thrift-based) and standard HTTP POSTs to LINE's messaging endpoints.
Frequently Asked Questions
How do I handle LIFF consent errors manually in LINEJS?
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →