12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

HerokuでLINEとDiscordをつないでみる

Last updated at Posted at 2020-09-15

はじめに

KC3 2020の勉強会で話した内容です。
DiscordとLINEでテキストメッセージのやり取りができるようにします。
画像のメッセージのやり取りの実装などは別記事でやります。

LINEでメッセージ送信 → LINE BotがHerokuにメッセージの内容を送信 → HerokuがDiscord Webhookにメッセージの内容を送信 → Discordでメッセージが表示される

Discordでメッセージ送信 → Discord BotがHerokuにメッセージの内容を送信 → HerokuがLINE Botにメッセージの内容を送信 → LINE Botが発言
大まかにはこのような構成になっています。

LINE Botの準備

LINE Developersにログイン

LINE Developersにログイン。LINEアカウントでログインできる。

Providerを作成

Providers一覧の上の”Create”ボタンを押し、名前を決めて新規作成。

Channelを作成

作成したProviderのChannelを作成する。Create a Messaging API Channelを選択。


入力項目を埋めてChannelを作成する。
このとき、ブラウザの拡張機能が干渉してインプットが消えてしまうことがあった。

LINE Botの設定を変更

LINE Official Account Managerの応答設定からLINE Botの設定のWebhookをオンにする。

LINE Botと友だちになる/グループに招待

グループに参加させるにはLINE DevelopersのChannel設定のMessaging APIタブからグループ参加を有効にする必要がある。
友だち追加はBasic settingsタブのQRコードなどから可能。
グループの各メンバーはBotを友だち追加する必要がある。

これでLINE Botの準備は完了。

環境変数の登録などの諸設定をするためにLINE Developersを開く。

Discord Botの準備

Discord Developer Portalにログイン

Discord Developer Portalにログインする。

Applicationを作成

右上の"New Application"を押して名前を指定し、Applicationを新規作成する。

Discord Botの作成

BotタブからBotを新規作成する。

Discord Botをサーバーに招待

OAuth2タブで適宜必要なチェックを入れて生成されたURLを開く。
そのページでBotをサーバーに招待する。

これでDiscord Botの準備は完了。Botはサーバーに参加していてオフラインの状態。

コードを書いてHerokuにデプロイ

Node.js(今回は12.8.3を使用)でHerokuで行う処理を記述する。

下準備

git initnpm initなど叩いてgit・npmが使える状態にする。ここは割愛。
Heroku CLIを使用するのでインストールしておく。

必要なパッケージの導入

$ npm install @line/bot-sdk discord.js express axios

を実行してパッケージを導入。

LINE → Discordの処理

jsファイルを作成してコードを書いていく。

linebot.js
const express = require('express');
const axios = require('axios');
const line = require('@line/bot-sdk');

const PORT = process.env.PORT || 5000;

const lineConfig = {
  channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.LINE_CHANNEL_SECRET,
};
const lineClient = new line.Client(lineConfig);

const discordWebhookUrl = process.env.DISCORD_WEBHOOK_URL;
const discordWebhookConfig = {
  headers: {
    'Accept': 'application/json',
    'Content-type': 'application/json',
  },
};

const generatePostData = (event, profile) => {
  const type = event.message.type;
  if (type !== 'text') {
    return {
      username: profile.displayName,
      avatar_url: `${profile.pictureUrl}.png`,
      content: 'テキスト以外のメッセージを送信しました。',
    };
  }
  return {
    username: profile.displayName,
    avatar_url: `${profile.pictureUrl}.png`,
    content: event.message.text,
  };
};

const lineBot = async (req, res) => {
  res.status(200).end(); // 'status 200'をLINEのAPIに送信

  const events = req.body.events;
  events.forEach(async (event) => {
    try {
      const profile =  await lineClient.getProfile(event.source.userId);
      const postData = await generatePostData(event, profile);
      // DiscordのWebHookにPOST
      await axios.post(discordWebhookUrl, postData, discordWebhookConfig);
    } catch(error) {
      console.error(error);
    }
  });
};

const app = express();
app.post('/linehook/', line.middleware(lineConfig), (req, res) => lineBot(req, res));
app.listen(PORT, () => console.log(`Listening on ${ PORT } for LINE Messaging API.`));

expressでLINE BotからのPOSTを受けてDiscord WebhookにPOSTしている。
LINEのアイコンと名前をDiscordで出力する際に反映させている。

Discord → LINEの処理

おなじくjsファイルを作成してコードを書いていく。

discordbot.js
const line = require('@line/bot-sdk');
const discord = require('discord.js');

const lineConfig = {
  channelAccessToken: process.env.LINE_CHANNEL_ACCESS_TOKEN,
  channelSecret: process.env.LINE_CHANNEL_SECRET,
};
const lineClient = new line.Client(lineConfig);

const discordClient = new discord.Client();

const generateMessage = (event) => {
  const content = event.content;
  if (content.length === 0) {
    return {
      type: 'text',
      text: 'Discordで非対応の形式のメッセージを送信しました。',
      sender: {
        name: event.author.username,
        iconUrl: event.author.displayAvatarURL().replace('.webp', '.png'),
      },
    };
  }
  return {
    type: 'text',
    text: `${content}`,
    sender: {
      name: event.author.username,
      iconUrl: event.author.displayAvatarURL().replace('.webp', '.png'),
    },
  };
};

discordClient.on('message', async (event) => {
  try {
    // BOTのメッセージはスルー
    if (!event.author.bot) {
      const message = generateMessage(event);
      await lineClient.pushMessage(
        // 送信先のトークルームのグループ/ユーザーID
        process.env.LINE_TARGET_ID,
        message,
      );
    }
  } catch(error) {
    console.error(error);
  } 
});

discordClient.login(process.env.DISCORD_ACCESS_TOKEN);

DiscordのアイコンとユーザーIDをLINE Botが発言するときに使用する。

Procfileの記述

Herokuでjsファイルが実行できるようにProcfileを書いておく。

line: node linebot.js
dicord: node discordbot.js

Herokuにデプロイ

Heroku スターターガイド (Node.js)にあるようにHeroku CLIでデプロイする。

まだこの時点では動作しない。

環境変数の登録などの諸設定

Heroku DashboardのSettingsのConfig Varsから環境変数を設定できる。
Heroku CLIからも可能。Herokuで環境変数を設定する方法 - Qiita
上のコードだと以下の5つを設定する。

LINEのChannel access token

LINE DevelopersのChannelの設定画面のMessaging APIタブの一番下にChannel access token (long-lived)がある。
上のコードではLINE_CHANNEL_ACCESS_TOKENとして設定する。

LINEのChannel secret

LINE DevelopersのChannel設定画面のBasic settingsタブにChannel secretがある。
上のコードではLINE_CHANNEL_SECRETとして設定する。

LINE Messaging APIのWebhook URLを設定

LINE DevelopersのChannelの設定画面のMessaging APIタブでWebhook URLを"https://<Herokuのアプリ名>.heroku.com/linehook"に設定する。
設定するとVerifyというボタンが出る。押してSuccessと出れば成功。

DiscordのWebhook URL

タイトル: Webhooksへの序章 – Discord - Discord SupportのようにWebhook URLを取得し、それを上のコードではDISCORD_WEBHOOK_URLとして設定する。

DiscordのToken

Discord Developer Portalの作成したアプリケーションの画面のBotタブからTokenを取得し、上のコードではDISCORD_ACCESS_TOKENとして設定する。

Botが発言するトークルームのID

LINE Botが発言するトークルームのIDを指定しておく必要がある。
グループチャット | LINE DevelopersにあるようにメッセージイベントのsourceプロパティからIDを取得できる。linebot.jsにコードを書き足してログに表示するようにしておけばHerokuの実行ログから確認できる。それを上のコードではLINE_TARGET_IDとして設定する。

dynoを起動

Heroku Dashboardからdynoを起動する。
これでテキストメッセージのやり取りはできるようになる。

参照

これらの記事も参考になると思います。

12
6
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?