npm package: @stardeckai/line-chat-adapter
Description: LINE Messaging API adapter for Chat SDK
Latest version: 0.2.1

# @stardeckai/line-chat-adapter

[![npm version](https://img.shields.io/npm/v/@stardeckai/line-chat-adapter)](https://www.npmjs.com/package/@stardeckai/line-chat-adapter)
[![npm downloads](https://img.shields.io/npm/dm/@stardeckai/line-chat-adapter)](https://www.npmjs.com/package/@stardeckai/line-chat-adapter)

LINE Messaging API adapter for [Chat SDK](https://chat-sdk.dev), using the [LINE Messaging API](https://developers.line.biz/en/docs/messaging-api/).

## Installation

```bash
pnpm add @stardeckai/line-chat-adapter
```

## Usage

```typescript
import { Chat } from "chat";
import { createLINEAdapter } from "@stardeckai/line-chat-adapter";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    line: createLINEAdapter(),
  },
});

bot.onNewMention(async (thread, message) => {
  await thread.post("Hello from LINE!");
});
```

When using `createLINEAdapter()` without arguments, credentials are auto-detected from environment variables.

## LINE Developers Console setup

### 1. Create a channel

1. Go to [developers.line.biz](https://developers.line.biz/) and log in
2. Create a new **Provider** (or select an existing one)
3. Create a new **Messaging API** channel
4. Fill in the required channel information

### 2. Get credentials

From your channel's **Basic settings** tab:

- **Channel Secret** as `LINE_CHANNEL_SECRET`

From your channel's **Messaging API** tab:

- Click **Issue** to generate a **Channel Access Token (long-lived)** as `LINE_CHANNEL_ACCESS_TOKEN`

### 3. Configure webhooks

1. Go to the **Messaging API** tab in your channel settings
2. Set **Webhook URL** to `https://your-domain.com/api/webhooks/line`
3. Enable **Use webhook**
4. Optionally disable **Auto-reply messages** and **Greeting messages** (these conflict with bot responses)

## Configuration

All options are auto-detected from environment variables when not provided. You can call `createLINEAdapter()` with no arguments if the env vars are set.

| Option | Required | Description |
|--------|----------|-------------|
| `channelAccessToken` | No* | Channel access token. Auto-detected from `LINE_CHANNEL_ACCESS_TOKEN` |
| `channelSecret` | No* | Channel secret for webhook verification. Auto-detected from `LINE_CHANNEL_SECRET` |
| `userName` | No | Bot username. Auto-detected from `LINE_BOT_USERNAME` (defaults to `line-bot`) |
| `logger` | No | Logger instance (defaults to `ConsoleLogger("info")`) |

*Required at runtime — either via config or environment variable.

## Environment variables

```bash
LINE_CHANNEL_ACCESS_TOKEN=...   # Long-lived channel access token
LINE_CHANNEL_SECRET=...         # Channel secret for signature verification
LINE_BOT_USERNAME=...           # Optional, defaults to "line-bot"
```

## Webhook setup

LINE sends all events as POST requests with JSON bodies. The adapter verifies the `X-Line-Signature` header using HMAC-SHA256.

```typescript
// Next.js App Router example
import { bot } from "@/lib/bot";

export async function POST(request: Request) {
  return bot.adapters.line.handleWebhook(request);
}
```

## Features

### Messaging

| Feature | Supported |
|---------|-----------|
| Post message | Yes |
| Edit message | No (LINE limitation) |
| Delete message | No (LINE limitation) |
| Streaming | Buffered (accumulates then sends) |
| Auto-chunking | Yes (splits at 5000 chars) |

### Rich content

| Feature | Supported |
|---------|-----------|
| Flex Messages | Yes (card element conversion) |
| Buttons | Yes (postback actions) |
| Link buttons | Yes (URI actions) |
| Fields | Yes (horizontal box layout) |
| Text fallback | Yes (for unsupported cards) |

### Conversations

| Feature | Supported |
|---------|-----------|
| Mentions | Yes (in groups) |
| Reactions | No (LINE API limitation) |
| Typing indicator | Yes (1:1 chats only, loading animation) |
| DMs | Yes |
| Open DM | Yes |
| Groups | Yes |

### Incoming message types

| Type | Supported |
|------|-----------|
| Text | Yes |
| Images | Yes |
| Video | Yes |
| Audio | Yes |
| Files | Yes |
| Location | Yes (converted to map URL) |
| Stickers | Yes (placeholder text) |
| Postback | Yes (button actions) |

### Message history

| Feature | Supported |
|---------|-----------|
| Fetch messages | No (LINE API limitation) |
| Fetch thread info | Yes (user profile / group summary) |

## Reply token behavior

LINE uses a dual messaging model:

- **Reply API** (free) — uses a `replyToken` from the webhook event, valid for ~30 seconds
- **Push API** (metered) — sends messages proactively using the user/group ID

The adapter automatically uses the Reply API when a fresh token is available, falling back to the Push API when the token has expired. This minimizes message costs.

## Thread ID format

```
line:{sourceType}:{sourceId}
```

Examples:
- `line:user:U1234567890abcdef` — 1:1 DM
- `line:group:C1234567890abcdef` — Group chat
- `line:room:R1234567890abcdef` — Room (legacy)

## Troubleshooting

### Webhook verification failing

- Confirm `LINE_CHANNEL_SECRET` matches the value in the LINE Developers Console
- Ensure the raw request body is not parsed/modified before verification

### Bot not responding

- Check that **Use webhook** is enabled in the Messaging API settings
- Verify **Auto-reply messages** is disabled (it can interfere with webhook delivery)
- Ensure your webhook URL is publicly accessible via HTTPS

### Reply token expired

- Reply tokens expire after ~30 seconds. If your handler takes longer, the adapter falls back to the Push API
- Push API messages count against your monthly free message quota

### Messages not sending in groups

- Ensure the bot has been added to the group
- In groups, `source.userId` may be absent if the bot doesn't have the "chat" permission — the adapter handles this with a fallback author

## License

MIT