はじめに
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の作成
Discord Botをサーバーに招待
OAuth2タブで適宜必要なチェックを入れて生成されたURLを開く。
そのページでBotをサーバーに招待する。
これでDiscord Botの準備は完了。Botはサーバーに参加していてオフラインの状態。
コードを書いてHerokuにデプロイ
Node.js(今回は12.8.3を使用)でHerokuで行う処理を記述する。
下準備
git init
やnpm init
など叩いてgit・npmが使える状態にする。ここは割愛。
Heroku CLIを使用するのでインストールしておく。
必要なパッケージの導入
$ npm install @line/bot-sdk discord.js express axios
を実行してパッケージを導入。
LINE → Discordの処理
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ファイルを作成してコードを書いていく。
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を起動する。
これでテキストメッセージのやり取りはできるようになる。
参照
- ドキュメントトップ | LINE Developers
- Discord Developer Portal
- Heroku Dev Center
- @line/bot-sdk - npm
- discord.js - npm
- express - npm
- axios - npm
- Herokuで環境変数を設定する方法 - Qiita
- Heroku Schedulerの設定方法 - Qiita
これらの記事も参考になると思います。