{"id":17491784,"url":"https://github.com/waynechang65/deno-linebot","last_synced_at":"2025-04-22T20:15:13.985Z","repository":{"id":46889945,"uuid":"408792048","full_name":"WayneChang65/deno-linebot","owner":"WayneChang65","description":"🦕 SDK for the LINE Messaging API for Deno.","archived":false,"fork":false,"pushed_at":"2021-11-15T14:10:35.000Z","size":36,"stargazers_count":16,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-22T20:15:08.121Z","etag":null,"topics":["bot","deno","deno-module","javascript","line","sdk"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WayneChang65.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-09-21T11:24:59.000Z","updated_at":"2023-12-10T16:46:17.000Z","dependencies_parsed_at":"2022-09-11T15:12:13.516Z","dependency_job_id":null,"html_url":"https://github.com/WayneChang65/deno-linebot","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WayneChang65%2Fdeno-linebot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WayneChang65%2Fdeno-linebot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WayneChang65%2Fdeno-linebot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WayneChang65%2Fdeno-linebot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WayneChang65","download_url":"https://codeload.github.com/WayneChang65/deno-linebot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250316066,"owners_count":21410476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bot","deno","deno-module","javascript","line","sdk"],"created_at":"2024-10-19T08:04:57.999Z","updated_at":"2025-04-22T20:15:13.963Z","avatar_url":"https://github.com/WayneChang65.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deno-linebot  \n\u003ca href=\"https://github.com/waynechang65/deno-linebot/tags/\"\u003e\u003cimg src=\"https://img.shields.io/github/tag/waynechang65/deno-linebot\" alt=\"Current version\" /\u003e\u003c/a\u003e \u003ca href=\"https://github.com/denoland/deno/blob/main/Releases.md\"\u003e\u003cimg src=\"https://img.shields.io/badge/deno-1.14.0-brightgreen?logo=deno\" alt=\"Minimum supported Deno version\" /\u003e\u003c/a\u003e \u003ca href=\"https://GitHub.com/waynechang65/deno-linebot/graphs/commit-activity\"\u003e\u003cimg src=\"https://img.shields.io/badge/Maintained%3F-yes-green.svg\" alt=\"deno-linebot is maintained\" /\u003e\u003c/a\u003e \u003cimg src=\"https://img.shields.io/github/license/waynechang65/deno-linebot\" alt=\"deno-linebot license\" /\u003e \u003ca href=\"https://nest.land/package/deno-linebot\"\u003e\u003cimg src=\"https://nest.land/badge.svg\" alt=\"Published on nest.land\" /\u003e\u003c/a\u003e   \n\u003cimg align=\"right\" src=\"https://deno.land/logo.svg\" height=\"80px\" width=\"80px\" alt=\"the deno mascot dinosaur standing in the rain\"\u003e  \n\n🤖 SDK for the LINE Messaging API for [Deno](https://deno.land/).  \n- Support [Opine](https://github.com/asos-craigmorten/opine) framework which ported from [ExpressJS](https://github.com/expressjs/express) for Deno  \n- Provide convenient addon functions to [event object](#event-object)  \n\n# About LINE Messaging API\n\nPlease refer to the official API documents for details.\n- Developer Documents - https://developers.line.biz/en/docs/\n- API Reference - https://developers.line.biz/en/reference/messaging-api/\n# Installation\nThis is a [Deno](https://deno.land/) module available to import direct from this repo and via the [Deno Registry](https://deno.land/x).  \nBefore importing, [download and install Deno](https://deno.land/#installation).  \n\nYou can then import linebot straight into your project:  \n\n### Import form [deno.land](https://deno.land/)  \n```javascript\nimport { linebot } from 'https://deno.land/x/linebot/mod.ts'\n```  \nOR  \n### Import form [nest.land](https://nest.land/)  \n```javascript\nimport { linebot } from 'https://x.nest.land/linebot/mod.ts'\n```  \n\n# Usage  \n:heavy_exclamation_mark: Notice: Check endpoint of the webhook is the same to 「Webhook URL」 of setting page to LINE Message API. (The demo is 'webhook')  \n\n## Using with your own [Opine](https://github.com/asos-craigmorten/opine) server  \n\n```javascript\n'use strict';\nimport { linebot } from 'https://deno.land/x/linebot/mod.ts';\nimport { opine, json } from 'https://deno.land/x/opine@1.8.0/mod.ts';\n\nconst endpointToWebHook = 'webhook';\nconst options = {\n   channelId: CHANNEL_ID,\n   channelSecret: CHANNEL_SECRET,\n   channelAccessToken: CHANNEL_ACCESS_TOKEN,\n   verify: true\n};\nconst bot = linebot(options);\nconst app = opine();\nconst linebotParser = bot.parser(json);\n\napp.post(`/${endpointToWebHook}`, linebotParser);\n\nbot.on('message', async (event) =\u003e {\n   try {\n      let result = await event.reply(event.message.text);\n      // Do something here as success\n      console.log('Success', result);\n   } catch (error) {\n      // Do something here to deal with error\n      console.log('Error', error);\n   }\n});\n\nconst port = parseInt(Deno.env.get('PORT')) || 80;\napp.listen(port, () =\u003e console.log('LineBot is running. Port : ' + port));\n```  \nSee [`examples`](examples) folder for more examples.  \n\n## Examples\n### Run the example using Deno directly from deno.land or nest.land, for example:\n```console\ndeno run --allow-read --allow-env --allow-net https://deno.land/x/linebot/examples/demo.js\n```\n### Or clone the linebot repo locally:\n```console\ngit clone https://github.com/WayneChang65/deno-linebot.git\ncd deno-linebot\ndeno run --allow-read --allow-env --allow-net ./examples/demo.js\n```\n\n# API\n\n## LineBot object\n\n### linebot(config)\nCreate LineBot instance with specified configuration.\n```js\nconst bot = linebot({\n  channelId: CHANNEL_ID,\n  channelSecret: CHANNEL_SECRET,\n  channelAccessToken: CHANNEL_ACCESS_TOKEN,\n  verify: true // Verify 'X-Line-Signature' header (default=true)\n});\n```\n\n## Basic  \n\n### LineBot.parser()\n\nCreate [Opine](https://github.com/asos-craigmorten/opine) middleware to parse the request.\n\nThe parser assumes that the request body has never been parsed by any body parser before,\nso it must be placed BEFORE any generic body parser.\n\n### LineBot.verify(rawBody, signature)\n\nVerify `X-Line-Signature` header.\n\n### LineBot.parse(body)\n\nProcess incoming webhook request, and raise an event.\n\n### LineBot.on(eventType, eventHandler)\n\nRaised when a [Webhook event][webhook-event-url] is received.\n```js\nbot.on('message',      async function (event) { });\nbot.on('follow',       async function (event) { });\nbot.on('unfollow',     async function (event) { });\nbot.on('join',         async function (event) { });\nbot.on('leave',        async function (event) { });\nbot.on('memberJoined', async function (event) { });\nbot.on('memberLeft',   async function (event) { });\nbot.on('postback',     async function (event) { });\nbot.on('beacon',       async function (event) { });\n```\n\n## Message\n\n### LineBot.reply(replyToken, message)\n\nReply a message.\n\nSee: [Event.reply(message)](#eventreplymessage)\n\n### LineBot.push(to, message)\n\nSend push message.\n\n`to` is a userId, or an array of userId.\nA userId can be saved from `event.source.userId`\nwhen added as a friend (follow event), or during the chat (message event).\n\n`message` can be a string, an array of string,\na [Send message][send-message-url] object,\nor an array of [Send message][send-message-url] objects.\n\n### LineBot.multicast(to, message)\n\nSend push message to multiple users (Max: 150 users).\nThis is more efficient than `push` as it will make api call only once.\n\n`to` is an array of userId.\n\n`message` can be a string, an array of string,\na [Send message][send-message-url] object,\nor an array of [Send message][send-message-url] objects.\n\n### LineBot.broadcast(message)\n\nSend push message to all users.\nThis is more efficient than `push` as it will make api call only once.\n\n`message` can be a string, an array of string,\na [Send message][send-message-url] object,\nor an array of [Send message][send-message-url] objects.\n\n### LineBot.getMessageContent(messageId)\n\nGet image, video, and audio data sent by users as a [Buffer][buffer-url] object.\n\nSee: [Event.message.content()](#eventmessagecontent)\n\n### LineBot.getQuota()\n\nGet the number of messages quota in the current month.  \n\n### LineBot.getTotalSentMessagesThisMonth()  \n\nGet number of messages sent this month.  \n\n### LineBot.getTotalReplyMessages(date)  \n\nGet number of sent reply messages.  \n \n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n### LineBot.getTotalPushMessages(date)  \n\nGet number of sent push messages.    \n\n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n### LineBot.getTotalBroadcastMessages(date)\n\nGet number of sent broadcast messages.    \n\n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n### LineBot.getTotalMulticastMessages(date)\n\nGet number of sent multicast messages.   \n\n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n## Insight  \n\n### LineBot.getTotalMessagesInsight(date)  \n\nGet number of message deliveries  \n\n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n### LineBot.getFriendDemographicsInsight()  \n\nGet friend demographics  \n\n### LineBot.getTotalFollowersInsight(date)\n\nGet the number of users who have added this linebot on or before a specified date.\n\n`date` Date the messages were sent  \n* Format: `yyyyMMdd` (Example: `20210909`)  \n* Timezone: UTC+9  \n* Default date is yesterday (UTC+9).  \n\n## Users  \n\n### LineBot.getUserProfile(userId)\n\nGet user profile information of the user.\n\n`userId` User ID that is returned in a webhook event object (e.g. U4af4980629...).  \n\nSee: [Event.source.profile()](#eventsourceprofile), [Event.left.profiles()](#eventleftprofiles)  \n\n## Bot  \n\n### LineBot.getBotInfo()  \n\nGet bot info  \n\n## Group  \n\n### LineBot.getGroupProfile(groupId)  \n\nGet a group profile.  \n\n`groupId` Group ID. Found in the source object of webhook event objects (e.g. Ca56f94637c...).  \n\nSee: [Event.source.profile()](#eventsourceprofile)  \n\n### LineBot.getGroupMembersCount(groupId)  \n\nGet number of users in a group.  \n\n`groupId` Group ID. Found in the source object of webhook event objects (e.g. Ca56f94637c...).  \n\n### LineBot.getGroupMember(groupId)\n\nGet userId of all members in a group.  \n\n`groupId` Group ID. Found in the source object of webhook event objects (e.g. Ca56f94637c...).  \n\nSee: [Event.source.member()](#eventsourcemember)  \n\n### LineBot.getGroupMemberProfile(groupId, userId)  \n\nGet user profile of a member in a group.  \n\nSee: [Event.joined.profiles()](#eventjoinedprofiles)  \n\n### LineBot.leaveGroup(groupId)  \n\nLeave a group.  \n\n`groupId` Group ID. Found in the source object of webhook event objects (e.g. Ca56f94637c...).  \n\n## Chatroom  \n\n### LineBot.getRoomMembersCount(roomId)  \n\nGet number of users in a room.  \n\n`roomId` Room ID. Found in the source object of webhook event objects.  \n\n### LineBot.getRoomMember(roomId)  \n\nGet userId of all members in a chat room.  \n\n`roomId` Room ID. Found in the source object of webhook event objects.  \n\nSee: [Event.source.member()](#eventsourcemember)  \n\n### LineBot.getRoomMemberProfile(roomId, userId)  \n\nGet user profile of a member in a chat room.  \n\n`roomId` Room ID. Found in the source object of webhook event objects.  \n\n`userId` User ID that is returned in a webhook event object (e.g. U4af4980629...).  \n\nSee: [Event.joined.profiles()](#eventjoinedprofiles)  \n\n### LineBot.leaveRoom(roomId)  \n\nLeave a room.  \n\n`roomId` Room ID. Found in the source object of webhook event objects.  \n\n## Account Link  \n\n\n### LineBot.getIssueLinkToken(userId)  \n\nIssue link token  \n\n`userId` User ID that is returned in a webhook event object (e.g. U4af4980629...).  \n\n## Event object\n\nProvide convenient shorthands to call LineBot's functions\nwhich require parameter from a source event object.\n\n### Event.reply(message)\n\nRespond to the event.\n\n`message` can be a string, an array of string,\na [Send message][send-message-url] object,\nor an array of [Send message][send-message-url] objects.\n\nReturn a [Promise][promise-url] object.\n\nThis is a shorthand for: `LineBot.reply(event.replyToken, message)`\n\n```js\n// reply text message\ntry {\n  result = await event.reply(event.message.text);\n  // Do something here as success\n  console.log('Success', result);\n} catch (error) {\n  // Do something here to deal with error\n  console.log('Error', error);\n}\n\n// reply multiple text messages\nevent.reply(['Hello, world 1', 'Hello, world 2']);\n\n// reply message object\nevent.reply({ type: 'text', text: 'Hello, world' });\n\n// reply multiple message object\nevent.reply([\n  { type: 'text', text: 'Hello, world 1' },\n  { type: 'text', text: 'Hello, world 2' }\n]);\n\nevent.reply({\n  type: 'image',\n  originalContentUrl: 'https://example.com/original.jpg',\n  previewImageUrl: 'https://example.com/preview.jpg'\n});\n\nevent.reply({\n  type: 'video',\n  originalContentUrl: 'https://example.com/original.mp4',\n  previewImageUrl: 'https://example.com/preview.jpg'\n});\n\nevent.reply({\n  type: 'audio',\n  originalContentUrl: 'https://example.com/original.m4a',\n  duration: 240000\n});\n\nevent.reply({\n  type: 'location',\n  title: 'my location',\n  address: '〒150-0002 東京都渋谷区渋谷２丁目２１−１',\n  latitude: 35.65910807942215,\n  longitude: 139.70372892916203\n});\n\nevent.reply({\n  type: 'sticker',\n  packageId: '1',\n  stickerId: '1'\n});\n\nevent.reply({\n  type: 'imagemap',\n  baseUrl: 'https://example.com/bot/images/rm001',\n  altText: 'this is an imagemap',\n  baseSize: { height: 1040, width: 1040 },\n  actions: [{\n    type: 'uri',\n    linkUri: 'https://example.com/',\n    area: { x: 0, y: 0, width: 520, height: 1040 }\n  }, {\n    type: 'message',\n    text: 'hello',\n    area: { x: 520, y: 0, width: 520, height: 1040 }\n  }]\n});\n\nevent.reply({\n  type: 'template',\n  altText: 'this is a buttons template',\n  template: {\n    type: 'buttons',\n    thumbnailImageUrl: 'https://example.com/bot/images/image.jpg',\n    title: 'Menu',\n    text: 'Please select',\n    actions: [{\n      type: 'postback',\n      label: 'Buy',\n      data: 'action=buy\u0026itemid=123'\n    }, {\n      type: 'postback',\n      label: 'Add to cart',\n      data: 'action=add\u0026itemid=123'\n    }, {\n      type: 'uri',\n      label: 'View detail',\n      uri: 'http://example.com/page/123'\n    }]\n  }\n});\n\nevent.reply({\n  type: 'template',\n  altText: 'this is a confirm template',\n  template: {\n    type: 'confirm',\n    text: 'Are you sure?',\n    actions: [{\n      type: 'message',\n      label: 'Yes',\n      text: 'yes'\n    }, {\n      type: 'message',\n      label: 'No',\n      text: 'no'\n    }]\n  }\n});\n\nevent.reply({\n  type: 'template',\n  altText: 'this is a carousel template',\n  template: {\n    type: 'carousel',\n    columns: [{\n      thumbnailImageUrl: 'https://example.com/bot/images/item1.jpg',\n      title: 'this is menu',\n      text: 'description',\n      actions: [{\n        type: 'postback',\n        label: 'Buy',\n        data: 'action=buy\u0026itemid=111'\n      }, {\n        type: 'postback',\n        label: 'Add to cart',\n        data: 'action=add\u0026itemid=111'\n      }, {\n        type: 'uri',\n        label: 'View detail',\n        uri: 'http://example.com/page/111'\n      }]\n    }, {\n      thumbnailImageUrl: 'https://example.com/bot/images/item2.jpg',\n      title: 'this is menu',\n      text: 'description',\n      actions: [{\n        type: 'postback',\n        label: 'Buy',\n        data: 'action=buy\u0026itemid=222'\n      }, {\n        type: 'postback',\n        label: 'Add to cart',\n        data: 'action=add\u0026itemid=222'\n      }, {\n        type: 'uri',\n        label: 'View detail',\n        uri: 'http://example.com/page/222'\n      }]\n    }]\n  }\n});\n```\n\n### Event.joined.profiles()\n\nGet user profiles information of the sender, when a user joins a group or room.\n\nThis is a shorthand for:\n  - `LineBot.getGroupMemberProfile(event.source.groupId, event.source.userId)` if bot is in a group\n  - `LineBot.getRoomMemberProfile(event.source.roomId, event.source.userId)` if bot is in a chat room\n\n```js\nlet profiles = await event.joined.profiles();\nconsole.log(profiles);\n```\n\n### Event.left.profiles()\n\nGet user profiles information of the sender, when a user leave a group or room.\n\nThis is a shorthand for:\n  - `LineBot.getUserProfile(event.source.userId)` if it is 1:1 chat\n\n```js\nlet profiles = await event.left.profiles();\nconsole.log(profiles);\n```\n\n### Event.source.profile()\n\nGet user profile information of the sender.\n\nThis is a shorthand for:\n  - `LineBot.getUserProfile(event.source.userId)` if it is 1:1 chat\n  - `LineBot.getGroupProfile(event.source.groupId)` if bot is in a group\n  - `LineBot.getGroupMemberProfile(event.source.groupId, event.source.userId)` if bot is in a group\n  - `LineBot.getRoomMemberProfile(event.source.roomId, event.source.userId)` if bot is in a chat room\n\n```js\nlet profile = await event.source.profile();\nawait event.reply('Hello ' + profile.displayName);\n```\n\n### Event.source.member()\n\nGet userId of all members in a group or a chat room.\n\nThis is a shorthand for:\n  - `LineBot.getGroupMember(event.source.groupId)` if bot is in a group\n  - `LineBot.getRoomMember(event.source.roomId)` if bot is in a chat room\n\n```js\nlet member = await event.source.member();\nconsole.log(member.memberIds);\n```\n\n### Event.message.content()\n\nGet image, video, and audio data sent by users as a [Buffer][buffer-url] object.\n\nThis is a shorthand for: `LineBot.getMessageContent(event.message.messageId)`\n\n```js\nlet content = await event.message.content();\nconsole.log(content.toString('base64'));\n```\n\n# FAQ\n* It shows @ts-expect-error because of version of Deno std library.  \n**Solution**: Add `--no-check` in Deno command and wait for updating modules.. e.g. \n```console\ndeno run --allow-read --allow-env --allow-net --no-check https://deno.land/x/linebot/examples/demo.js\n```  \n\n# Contribution    \nEven though deno-linebot is a small project, I hope it can be improving. If there is any issue, please comment and welcome to fork for sending Pull Request. Thanks. :smile:  \n\n# Contributors  \nSpecial thanks to original designer of the node.js linebot project. [boybundit/linebot][boybundit-linebot-url]  \n\n# License  \n  [MIT](LICENSE)\n\n[webhook-event-url]: https://developers.line.biz/en/reference/messaging-api/#webhooks  \n[send-message-url]: https://developers.line.biz/en/reference/messaging-api/#message-objects  \n[buffer-url]: https://nodejs.org/api/buffer.html  \n[promise-url]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise  \n[boybundit-linebot-url]: https://github.com/boybundit/linebot  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaynechang65%2Fdeno-linebot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwaynechang65%2Fdeno-linebot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaynechang65%2Fdeno-linebot/lists"}