npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sadwx/line-exec-approval-plugin

v1.1.0

Published

OpenClaw plugin: LINE Flex Message cards for exec approval requests

Readme

line-exec-approval-plugin

OpenClaw plugin — deliver exec approval requests to LINE as interactive Flex Message cards

When OpenClaw asks for permission to run a shell command, this plugin pushes a rich card to LINE with three tap-to-approve buttons. No need to switch to a browser or another app.

Approval card preview


How It Works

  1. Subscribes to exec.approval.requested events from the local OpenClaw gateway via WebSocket
  2. Pushes a LINE Flex Message card to the configured approver with three buttons:
    • ✅ Allow Once — approve this command, this time only
    • ⭐ Allow Always — add to allowlist and approve permanently
    • ❌ Deny — block the command
  3. Tapping a button sends /approve <id> <decision> through LINE, which OpenClaw resolves

Works alongside other approval channels (e.g. Discord buttons). The first channel to resolve wins.

Screenshots

Approval card

When an exec command requires approval, a Flex Message card is pushed to LINE:

The card appears the same across all button action modes. The difference is what happens after a button is tapped.

Button action modes

silent — nothing appears in chat after tapping (default)

silent mode


friendly — shows the button label (e.g. ✅ Allow Once)

friendly mode


command — shows the raw /approve command text

command mode


Prerequisites

OpenClaw

  • OpenClaw gateway installed and running (tested on v2026.3.8+)
  • exec approvals enabled in your OpenClaw config:
{
  "agents": {
    "defaults": {
      "sandbox": {
        "mode": "all"
      }
    }
  }
}

LINE

  • A LINE Developers account
  • A Messaging API channel with:
    • A valid channel access token (long-lived token recommended)
    • Webhook enabled and pointing to your OpenClaw gateway, e.g. https://your-domain/line/webhook
  • The approver must add the LINE bot as a friend before push messages can be received

Push quota: The free plan allows 200 push messages/month per channel. Consider using a dedicated channel for this plugin to keep its quota separate from other bots.


Installation

Option A: Local path

Clone or download this repo, then add to ~/.openclaw/openclaw.json:

{
  "plugins": {
    "allow": ["line-exec-approval-plugin"],
    "load": {
      "paths": ["/path/to/line-exec-approval-plugin"]
    },
    "entries": {
      "line-exec-approval-plugin": {
        "enabled": true,
        "config": {
          "lineUserId": "U1234567890abcdef1234567890abcdef",
          "channelAccessTokenFile": "/path/to/line-channel-access-token.txt"
        }
      }
    }
  }
}

Restart the gateway to load the plugin.

Option B: npm (once published)

openclaw plugins install openclaw-line-exec-approval-plugin

Then add the plugins.entries config block above (without plugins.load.paths).


Configuration

| Field | Type | Required | Description | |---|---|---|---| | lineUserId | string | ✅ | LINE user ID of the approver (starts with U, 33 chars total) | | channelAccessToken | string | — | Inline plaintext channel access token | | channelAccessTokenFile | string | — | Path to a file containing the channel access token | | channelAccessTokenEnv | string | — | Name of an environment variable containing the channel access token | | buttonAction | string | — | How buttons behave when tapped: "command", "friendly", or "silent" (default: "silent") | | enabled | boolean | — | Set to false to disable without removing config (default: true) |

Exactly one of channelAccessToken, channelAccessTokenFile, or channelAccessTokenEnv should be set. If none are set, the plugin falls back to the LINE channel config in OpenClaw.

Token resolution order

  1. config.channelAccessToken — inline plaintext value
  2. config.channelAccessTokenFile — content of the specified file
  3. config.channelAccessTokenEnv — value of the named environment variable
  4. channels.line.channelAccessToken / channels.line.tokenFile — inherited from the default LINE channel in OpenClaw config
  5. LINE_CHANNEL_ACCESS_TOKEN environment variable

Full config example

{
  "plugins": {
    "allow": ["line-exec-approval-plugin"],
    "load": {
      "paths": ["/home/user/.openclaw/plugins/line-exec-approval-plugin"]
    },
    "entries": {
      "line-exec-approval-plugin": {
        "enabled": true,
        "config": {
          "lineUserId": "U1234567890abcdef1234567890abcdef",
          "channelAccessTokenFile": "/home/user/.openclaw/secrets/line-token.txt"
        }
      }
    }
  }
}

Button action modes

Controls what appears in the LINE chat when an approval button is tapped.

| Value | Chat behaviour | Notes | |---|---|---| | "silent" | Nothing appears in chat (default) | Cleanest UX; approval resolves silently | | "friendly" | Shows the button label (e.g. ✅ Allow Once) | Visible confirmation without raw commands | | "command" | Shows the raw /approve <id> allow-once text | Original behaviour; useful for debugging |

{
  "config": {
    "lineUserId": "U1234567890abcdef1234567890abcdef",
    "channelAccessTokenFile": "/path/to/token.txt",
    "buttonAction": "silent"
  }
}

Finding Your LINE User ID

Add your bot as a LINE friend, send it any message, then check the gateway logs:

openclaw channels logs --channel line

Your user ID appears in the inbound session key:

agent:main:line:direct:<userId>

The <userId> part (starting with U) is what you need.


Using Multiple LINE Channels

If you have multiple Messaging API channels configured in OpenClaw (e.g. default and dev), point this plugin to a specific channel's token to control which channel's push quota is used:

{
  "config": {
    "lineUserId": "U1234567890abcdef1234567890abcdef",
    "channelAccessTokenFile": "/home/user/.openclaw/secrets/line-dev-token.txt"
  }
}

LINE user IDs are scoped per provider (not per channel), so your user ID is the same across all channels under the same provider.


LINE Push Message Quota

| Plan | Monthly push limit | |---|---| | Free | 200 messages | | Light | 1,000 messages | | Standard | Unlimited |

Tip: Create a dedicated LINE Messaging API channel for approval notifications so its quota stays separate from channels used for regular messaging.


Troubleshooting

No Flex Message received after a command runs

  • Confirm the approver has added the bot as a LINE friend
  • Check gateway logs for LINE push failed — HTTP 429 means quota is exhausted
  • Verify lineUserId is correct (run openclaw channels logs --channel line and look for the session key)

gateway auth OK not appearing in logs

  • The gateway may not be running — check openclaw gateway status
  • The gateway auth token may be wrong — verify channels.gateway.auth.token in your config

Buttons do nothing when tapped

  • The LINE channel's webhook must be active and pointing to your gateway
  • The webhook URL must be reachable from LINE's servers (Cloudflare Tunnel or similar)

Command shows as (unknown) on the card

  • Normal for sandbox initialization execs where the command field is empty
  • Real user-triggered exec commands will display correctly

Development

npm run typecheck    # TypeScript type check
npm run lint         # ESLint
npm run lint:fix     # ESLint with auto-fix
npm run format       # Prettier
npm run build        # Compile to dist/

Project structure

src/
  types.ts           — Plugin config and OpenClaw API type stubs
  flex-builder.ts    — LINE Flex Message card builder
  gateway-client.ts  — Gateway WebSocket subscriber
  line-sender.ts     — LINE push message API + token resolution
  index.ts           — Plugin entry point

License

MIT