Node.js、Telegraf、Jimp、およびPexelsを使用してTelegramQuotesGeneratorボットを構築する方法
著者は、 Write for DOnations プログラムの一環として、 Free and Open SourceFundを選択して寄付を受け取りました。
序章
このチュートリアルでは、 Node.js 、 telegraf 、 jimp 、および PexelsAPIを使用してTelegramを構築しますファクトがオーバーレイされたランダムに選択された画像を送信するチャットボット。 Telegramボットは、好みのTelegramクライアントを介してカスタムスラッシュコマンドを使用して対話できるボットです。 Telegramを使用してボットを作成し、JavaScriptを使用してランダムな動物の画像と動物のファクトを選択するロジックを定義します。
このチュートリアルの最後に、次のようなTelegramチャットボットがあります。
ボットを完成させると、カスタムのTelegramスラッシュコマンドを送信するたびに、動物に関する事実を受け取ることができます。
前提条件
このチュートリアルに従うには、読者は次のツールが必要になります。
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成に従って実行できます。
- Telegram アカウントを登録して、ご希望のTelegramクライアントを選択します。
- 無料の写真やビデオをダウンロードできるPexelsアカウント。
このチュートリアルは、Nodev12.18.2およびnpmv6.14.8で検証されました。
ステップ1—プロジェクトルートディレクトリを作成する
このセクションでは、チャットボットをビルドするディレクトリを作成し、Nodeプロジェクトを作成して、必要な依存関係をインストールします。
ターミナルウィンドウを開き、facts-bot
という名前の新しいディレクトリを作成します。
mkdir facts-bot
ディレクトリに移動します。
cd facts-bot
temp
という名前のディレクトリを作成します。
mkdir temp
上記のコマンドを使用して、temp
という名前のディレクトリを作成しました。 このディレクトリには、ボットがユーザーに送信する画像を一時的に保存します。
次に、新しいNode.jsプロジェクトを作成します。 npmのinit
コマンドを実行すると、package.json
ファイルが作成され、依存関係とメタデータが管理されます。
初期化コマンドを実行します。
npm init
デフォルト値を受け入れるには、ENTER
を押してすべてのプロンプトを表示します。 または、応答をパーソナライズすることもできます。 これを行うには、チュートリアルnpmおよびpackage.jsonでNode.jsモジュールを使用する方法のステップ1でnpmの初期化設定を確認します。
package.jsonファイルを開き、編集します。
nano package.json
次に、package.json
ファイルのプロパティを更新します。 ファイル内の内容を強調表示されたコードに置き換えます。
package.json
{ "name": "facts-bot", "version": "1.0.0", "description": "", "main": "main.js", "scripts": { "start": "nodemon main.js" }, "author": "", "license": "ISC" }
ここでは、main
およびscripts
プロパティを変更しました。 main
プロパティを変更することにより、アプリケーションのメインファイルをmain.js
に設定しました。 これにより、main.js
ファイルがプログラムへの主要なエントリポイントであることがノードに通知されます。 scripts
プロパティに、start
という名前のscript
を追加しました。これにより、アプリケーションの起動時に実行されるはずのコマンドを設定できます。 script
を呼び出すと、コマンドnodemon
は、次のステップで作成するmain.js
ファイルを実行します。
package.json
ファイルで設定が定義されたら、環境変数を保存するファイルを作成します。 ターミナルで、.env
という名前のファイルを作成します。
touch .env
.env
ファイルに、TelegramボットトークンとPexelsAPIキーを保存します。 Telegram Botトークンを使用すると、Telegramボットと対話できます。 Pexels APIキーを使用すると、PexelsAPIを操作できます。 後のステップで環境変数を保存します。
今回は、npm
を使用して、依存関係telegraf
、dotenv
、pexels
、jimp
、および[をインストールします。 X112X]。 また、--save
フラグを使用して依存関係を保存します。 ターミナルで、次のコマンドを実行します。
npm install telegraf dotenv pexels jimp uuid --save
このコマンドでは、以下をインストールしました。
- telegraf :JavaScriptまたはTypeScriptを使用して独自のTelegramボットを開発するのに役立つライブラリ。 これを使用してボットを構築します。
- dotenv :環境変数を
.env
ファイルからprocess.env
にロードするゼロ依存モジュール。 このモジュールを使用して、作成した.env
ファイルからボットトークンとPexelsAPIキーを取得します。 - pexels :Node.jsのサーバーとブラウザーの両方で使用できるPexelsAPIの便利なラッパー。 このモジュールを使用して、Pexelsから動物の画像を取得します。
- jimp :Node用にJavaScriptで完全に記述された画像処理ライブラリで、外部またはネイティブの依存関係はありません。 このライブラリを使用して、Pexelsから取得した画像を編集し、動物に関する事実を挿入します。
- uuid :JavaScriptでRFC準拠のUUIDを生成できるようにするモジュール。 このモジュールを使用して、Pexelsから取得した画像の一意の名前を作成します。
次に、nodemonを開発依存関係としてインストールします。
npm install nodemon --save-dev
nodemon は、ディレクトリ内のファイルの変更を検出したときにNodeアプリケーションを自動的に再起動することにより、Node.jsベースのアプリケーションを開発するツールです。 このモジュールを使用して、ボットをテストしながらアプリを起動して実行し続けます。
注:これを書いている時点では、使用されているモジュールのバージョンは次のとおりです。telegraf
:4.3.0; dotenv
:8.2.0; pexels
:1.2.1; jimp
:0.16.1; uuid
:8.3.2; nodemon
:2.0.12。
このステップでは、プロジェクトディレクトリを作成し、ボットのNode.jsプロジェクトを初期化しました。 ボットの構築に必要なモジュールもインストールしました。 次のステップでは、ボットをTelegramに登録し、PexelsAPIのAPIキーを取得します。
ステップ2—ボットを登録してPexelsAPIからAPIキーを取得する
このセクションでは、最初にボットを BotFather に登録し、次にPexelsAPIのAPIキーを取得します。 BotFatherは、Telegramによって管理されるチャットボットであり、ユーザーがチャットボットを作成および管理できるようにします。
お好みのテレグラムクライアントを開き、@BotFather
を検索して、チャットを開始します。 /newbot
スラッシュコマンドを送信し、BotFatherから送信された指示に従います。
ボット名とユーザー名を選択すると、ボットアクセストークンを含むメッセージが表示されます。
ボットトークンをコピーして、.env
ファイルを開きます。
nano .env
BOT_TOKEN
という名前の変数にボットトークンを保存します。
.env
BOT_TOKEN = "Your bot token"
ボットトークンを.env
ファイルに保存したので、次はPexelsAPIキーを取得します。
Pexels に移動し、Pexelsアカウントにログインします。 クリックしてください画像と動画のAPI タブをクリックして、新しいAPIキーを作成します。
APIキーをコピーし、.env
ファイルを開きます。
nano .env
APIキーをPEXELS_API_KEY
という名前の変数に保存します。 .env
は次のようになります。
.env
BOT_TOKEN = "Your_bot_token" PEXELS_API_KEY = "Your_Pexels_API_key"
このセクションでは、ボットを登録し、Pexels APIキーを取得し、ボットトークンとPexelsAPIキーを.env
ファイルに保存しました。 次のセクションでは、ボットの実行を担当するファイルを作成します。
ステップ3—main.js
ファイルを作成する
このセクションでは、ボットを作成して構築します。 main.js
というラベルのファイルを作成します。これには、ボットのロジックが含まれます。
プロジェクトのルートディレクトリで、お好みのテキストエディタを使用してmain.js
ファイルを作成して開きます。
nano main.js
main.js
ファイル内に、使用するライブラリをインポートするための次のコードを追加します。
main.js
const { Telegraf } = require('telegraf') const { v4: uuidV4 } = require('uuid') require('dotenv').config() let factGenerator = require('./factGenerator')
このコードブロックでは、telegraf
、uuid
、dotenv
モジュール、およびfactGenerator.js
という名前のファイルが必要です。 telegraf
モジュールを使用してボットを起動および管理し、uuid
モジュールを使用してイメージの一意のファイル名を生成し、dotenv
モジュールを使用して.env
ファイルに保存されているテレグラムボットトークンとPexelsAPIキー。 factGenerator.js
ファイルは、Pexelsからランダムな動物の画像を取得し、動物に関する事実を挿入し、ユーザーに送信された後に画像を削除するために使用されます。 このファイルは次のセクションで作成します。
require
ステートメントの下に、次のコードを追加してボットのインスタンスを作成します。
main.js
. . . const bot = new Telegraf(process.env.BOT_TOKEN) bot.start((ctx) => { let message = ` Please use the /fact command to receive a new fact` ctx.reply(message) })
ここでは、BotFatherが送信したBOT_TOKEN
を取得して使用し、新しいボットインスタンスを作成して、bot
という変数に割り当てました。 新しいボットインスタンスを作成した後、/start
コマンドのコマンドリスナーを追加しました。 このコマンドは、ユーザーとボットの間の会話を開始する役割を果たします。 ユーザーが/start
を含むメッセージを送信すると、ボットは/fact
コマンドを使用して新しいファクトを受信するようにユーザーに求めるメッセージで応答します。
これで、チャットボットとの対話を開始するコマンドハンドラーが作成されました。 それでは、ファクトを生成するためのコマンドハンドラーを作成しましょう。 .start()
コマンドの下に、次のコードを追加します。
main.js
. . . bot.command('fact', async (ctx) => { try { ctx.reply('Generating image, Please wait !!!') let imagePath = `./temp/${uuidV4()}.jpg` await factGenerator.generateImage(imagePath) await ctx.replyWithPhoto({ source: imagePath }) factGenerator.deleteImage(imagePath) } catch (error) { console.log('error', error) ctx.reply('error sending image') } }) bot.launch()
このコードブロックでは、カスタム/fact
スラッシュコマンドのコマンドリスナーを作成しました。 このコマンドがTelegramユーザーインターフェイスからトリガーされると、ボットはユーザーにメッセージを送信します。 uuid
モジュールは、イメージ名とパスを生成するために使用されます。 画像は、ステップ1で作成した/temp
ディレクトリに保存されます。 その後、画像パスがgenerateImage()
という名前のメソッドに渡され、factGenerator.js
ファイルで定義して、動物に関する事実を含む画像を生成します。 画像が生成されると、画像がユーザーに送信されます。 次に、factGenerator.js
ファイルのdeleteFile
という名前のメソッドに画像パスが渡され、画像が削除されます。 最後に、bot.launch()
メソッドを呼び出してボットを起動しました。
main.js
ファイルは次のようになります。
main.js
const { Telegraf } = require('telegraf') const { v4: uuidV4 } = require('uuid') require('dotenv').config() let factGenerator = require('./factGenerator') const bot = new Telegraf(process.env.BOT_TOKEN) bot.start((ctx) => { let message = ` Please use the /fact command to receive a new fact` ctx.reply(message) }) bot.command('fact', async (ctx) => { try { ctx.reply('Generating image, Please wait !!!') let imagePath = `./temp/${uuidV4()}.jpg` await factGenerator.generateImage(imagePath) await ctx.replyWithPhoto({ source: imagePath }) factGenerator.deleteImage(imagePath) } catch (error) { console.log('error', error) ctx.reply('error sending image') } }); bot.launch()
ボットの実行と管理を担当するファイルを作成しました。 ここで、動物のファクトを設定し、factGenerator.js
ファイルでボットのロジックを構築します。
ステップ4—ファクトジェネレータファイルの作成とボットロジックの構築
このセクションでは、fact.js
およびfactGenerator.js
という名前のファイルを作成します。 fact.js
は、動物に関する事実を1つのデータソースに保存します。 factGenerator.js
ファイルには、ファイルから動物に関するランダムなファクトを取得し、Pexelsから画像を取得し、jimp
を使用して取得した画像にファクトを書き込み、削除するために必要なコードが含まれます。画像。
プロジェクトのルートディレクトリで、お好みのテキストエディタを使用してfacts.js
ファイルを作成して開きます。
nano facts.js
facts.js
ファイル内に、次のコードを追加してデータソースを作成します。
facts.js
const facts = [ { fact: "Mother pandas keep contact with their cub nearly 100% of the time during their first month - with the cub resting on her front and remaining covered by her paw, arm or head.", animal: "Panda" }, { fact: "The elephant's temporal lobe (the area of the brain associated with memory) is larger and denser than that of people - hence the saying 'elephants never forget'.", animal: "Elephant" }, { fact: "On average, males weigh 190kg and females weigh 126kg . They need this weight and power behind them to hunt large prey and defend their pride. ", animal: "Lion" }, { fact: "The Amazon river is home to four species of river dolphin that are found nowhere else on Earth. ", animal: "Dolphin" }, ] module.exports = { facts }
このコードブロックでは、動物に関する事実を含む配列を使用してオブジェクトを定義し、facts
という名前の変数に格納しました。 各オブジェクトには、fact
およびanimal
のプロパティがあります。 fact
という名前のプロパティでは、その値は動物に関する事実であり、プロパティanimal
には動物の名前が格納されます。 最後に、facts
アレイをエクスポートしています。
次に、factGenerator.js
という名前のファイルを作成します。
nano factGenerator.js
factGenerator.js
ファイル内に、動物の画像を作成するためのロジックを構築するために使用する依存関係に必要な次のコードを追加します。
factGenerator.js
let { createClient } = require('pexels') let Jimp = require('jimp') const fs = require('fs') let { facts } = require('./facts')
ここでは、pexels
、jimp
、fs
モジュール、およびfacts.js
ファイルが必要です。 pexels
モジュールを使用してPexelsから動物の画像を取得し、jimp
モジュールを使用してPexelsから取得した画像を編集し、fs
モジュールを使用してファイルから画像を削除します。ユーザーに送信された後のディレクトリ。
require
ステートメントの下に、次のコードを追加して画像を生成します。
factGenerator.js
. . . async function generateImage(imagePath) { let fact = randomFact() let photo = await getRandomImage(fact.animal) await editImage(photo, imagePath, fact.fact) }
このコードブロックでは、generateImage()
という名前の関数を作成しました。 この関数は、ファイルディレクトリ内のPexelイメージのパスを引数として取ります。 この関数が呼び出されると、randomFact()
という名前の関数が呼び出され、返された値がfact
という名前の変数に格納されます。 randomFact()
関数は、facts.js
ファイル内のオブジェクトをランダムに選択します。 オブジェクトを受け取った後、そのプロパティanimal
はgetRandomImage()
という名前の関数に渡されます。 getRandomImage()
関数は、pexels
モジュールを使用して、渡された動物の名前を含む画像を検索し、ランダムな画像を選択します。 返された値は、photo
という名前の変数に格納されます。 最後に、photo
、imagePath
、およびfacts.js
ファイルのfact
プロパティが、editImage()
という名前の関数に渡されます。 editImage()
機能は、jimp
モジュールを使用してランダムファクトをランダム画像に挿入し、編集した画像をimagePath
に保存します。
ここでは、/fact
スラッシュコマンドをボットに送信するときに呼び出される関数を作成しました。 次に、関数getRandomImage()
およびeditImage()
を作成し、ランダムな画像の選択と編集の背後にあるロジックを構築します。
generateImage()
関数の下に、次のコードを追加してランダム化ロジックを設定します。
factGenerator.js
. . . function randomFact() { let fact = facts[randomInteger(0, (facts.length - 1))] return fact } function randomInteger(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }
これで、関数randomFact()
およびrandomInteger()
が作成されました。 randomFact()
関数は、randomInteger()
関数を呼び出して、facts.js
ファイル内のランダムなfact
を選択し、このオブジェクトを返します。 randomInteger()
関数は、0の間隔のランダムな整数とfacts.js
ファイル内のファクトの数を返します。
ランダムなファクトとランダムな整数を返す関数を定義したので、Pexelsからランダムな画像を取得する関数を作成する必要があります。 randomInteger()
関数の下に、次のコードを追加してランダムな画像を取得します。
factGenerator.js
. . . async function getRandomImage(animal) { try { const client = createClient(process.env.PEXELS_API_KEY) const query = animal let image await client.photos.search({ query, per_page: 10 }).then(res => { let images = res.photos image = images[randomInteger(0, (images.length - 1))] }) return image } catch (error) { console.log('error downloading image', error) getRandomImage(animal) } }
このコードブロックでは、getRandomImage()
という名前の関数を作成しました。 この関数は、引数として動物の名前を取ります。 この関数が呼び出されると、client
オブジェクトは、pexels
モジュールのcreateClient()
メソッドオブジェクトと.env
ファイルに格納されているPexelsAPIキーを使用して作成されます。 動物名はquery
という変数に格納され、client
オブジェクトを使用してquery
の値を含む画像が検索されます。 画像が見つかると、randomInteger()
機能を使用してランダムな画像が選択されます。 最後に、ランダム画像がmain.js
ファイルのgenerateImage()
メソッドに返されます。
getRandomImage()
機能を使用すると、選択した画像をTelegramボットに送信する前にテキストオーバーレイを作成する必要があります。 getRandomImage()
関数の下に、次のコードを追加してオーバーレイを設定します。
factGenerator.js
. . . async function editImage(image, imagePath, fact) { try { let imgURL = image.src.medium let animalImage = await Jimp.read(imgURL).catch(error => console.log('error ', error)) let animalImageWidth = animalImage.bitmap.width let animalImageHeight = animalImage.bitmap.height let imgDarkener = await new Jimp(animalImageWidth, animalImageHeight, '#000000') imgDarkener = await imgDarkener.opacity(0.5) animalImage = await animalImage.composite(imgDarkener, 0, 0); } catch (error) { console.log("error editing image", error) } }
ここでは、editImage()
という名前の関数を作成しました。 この関数は、引数としてimage
、imagePath、およびこのランダムな動物に関するfact
というラベルの付いたランダムな動物を取ります。 変数imgURL
では、中サイズの画像のURLがPexelsAPIから取得されます。 その後、jimp
のread()
メソッドを使用して画像をロードします。 画像がanimalImage
という名前の変数に読み込まれて保存されると、画像の幅と高さが取得され、それぞれ変数animalImageWidth
とanimalImageHeight
に保存されます。 変数imgDarkener
は、Jimp()
の新しいインスタンスを格納し、画像を暗くします。 jimp
のopacity()
メソッドを使用して、imgDarkener
の不透明度を50%に設定します。 最後に、jimp
のcomposite()
メソッドを使用して、animalImage
の画像の上にimgDarkener
のコンテンツを配置します。 これにより、fact
変数に格納されているテキストを追加する前に、animalImage
の画像が暗くなり、画像上にテキストが表示されます。
注: Jimpはデフォルトで、画像の色調レベルを調整できるcolor()
という名前のメソッドを提供します。 color()
メソッドはここで必要な精度を提供しないため、このチュートリアルの目的のために、カスタムトーンアジャスターを作成します。
editImage()
関数内のtry
ブロックの下部に、次のコードを追加します。
factGenerator.js
. . . async function editImage(image, imagePath,fact) { try { . . . let posX = animalImageWidth / 15 let posY = animalImageHeight / 15 let maxWidth = animalImageWidth - (posX * 2) let maxHeight = animalImageHeight - posY let font = await Jimp.loadFont(Jimp.FONT_SANS_16_WHITE) await animalImage.print(font, posX, posY, { text: fact, alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER, alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE }, maxWidth, maxHeight) await animalImage.writeAsync(imagePath) console.log("Image generated successfully") } catch (error) { . . . } }
このコードブロックでは、animalImageWidth
とanimalImageHeight
を使用して、animalImage
のテキストを中央に配置するために使用される値を取得しました。 その後、jimp
のloadFont()
メソッドを使用してフォントをロードし、font
という名前の変数にフォントを格納しました。 フォントの色は白、タイプはsans-serif(SANS
)、サイズは16です。 最後に、jimp
のprint()
メソッドを使用してfact
をanimalImage
に挿入し、write()
メソッドを使用して[ imagePath
のX135X]。
画像の編集を担当する関数を作成したので、ユーザーに画像を送信した後、ファイル構造から画像を削除する関数が必要になります。 editImage()
関数の下に、次のコードを追加します。
factGenerator.js
. . . const deleteImage = (imagePath) => { fs.unlink(imagePath, (err) => { if (err) { return } console.log('file deleted') }) } module.exports = { generateImage, deleteImage }
ここでは、deleteImage()
という名前の関数を作成しました。 この関数は、引数として変数imagePath
を取ります。 この関数が呼び出されると、fs
モジュールを使用して、変数imagePath
に格納されている画像が削除されます。 最後に、generateImage()
関数とdeleteImage()
関数をエクスポートしました。
関数を配置すると、factGenerator.js
ファイルは次のようになります。
factGenerator.js
let { createClient } = require('pexels') let Jimp = require('jimp') const fs = require('fs') let { facts } = require('./facts') async function generateImage(imagePath) { let fact = randomFact() let photo = await getRandomImage(fact.animal) await editImage(photo, imagePath, fact.fact) } function randomFact() { let fact = facts[randomInteger(0, (facts.length - 1))] return fact } function randomInteger(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } async function getRandomImage(animal) { try { const client = createClient(process.env.PEXELS_API_KEY) const query = animal let image await client.photos.search({ query, per_page: 10 }).then(res => { let images = res.photos image = images[randomInteger(0, (images.length - 1))] }) return image } catch (error) { console.log('error downloading image', error) getRandomImage(animal) } } async function editImage(image, imagePath, fact) { try { let imgURL = image.src.medium let animalImage = await Jimp.read(imgURL).catch(error => console.log('error ', error)) let animalImageWidth = animalImage.bitmap.width let animalImageHeight = animalImage.bitmap.height let imgDarkener = await new Jimp(animalImageWidth, animalImageHeight, '#000000') imgDarkener = await imgDarkener.opacity(0.5) animalImage = await animalImage.composite(imgDarkener, 0, 0); let posX = animalImageWidth / 15 let posY = animalImageHeight / 15 let maxWidth = animalImageWidth - (posX * 2) let maxHeight = animalImageHeight - posY let font = await Jimp.loadFont(Jimp.FONT_SANS_16_WHITE) await animalImage.print(font, posX, posY, { text: fact, alignmentX: Jimp.HORIZONTAL_ALIGN_CENTER, alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE }, maxWidth, maxHeight) await animalImage.writeAsync(imagePath) console.log("Image generated successfully") } catch (error) { console.log("error editing image", error) } } const deleteImage = (imagePath) => { fs.unlink(imagePath, (err) => { if (err) { return } console.log('file deleted') }) } module.exports = { generateImage, deleteImage }
factGenerator.js
ファイルを保存します。 ターミナルに戻り、次のコマンドを実行してボットを起動します。
npm start
好みのTelegramクライアントを開き、ボットを検索します。 /start
コマンドでメッセージを送信して会話を開始するか、開始ボタンをクリックします。 次に、/fact
コマンドでメッセージを送信して、画像を受信します。
次のような画像が表示されます。
これで、画像にファクトが課された、好みのTelegramクライアントに画像が表示されます。 facts.js
ファイルからランダムなファクトを取得し、Pexelsから動物の画像を取得し、画像にファクトを挿入するファイルと関数を作成しました。
結論
このチュートリアルでは、カスタムのスラッシュコマンドを使用してファクトをオーバーレイした動物の画像を送信するTelegramチャットボットを作成しました。 telegraf
モジュールを使用してボットのコマンドハンドラーを作成しました。 また、pexels
モジュールを使用してPexelsからランダムなファクト、ランダムな画像を取得し、jimp
モジュールを使用してランダムな画像にファクトを挿入する関数を作成しました。 Pexels API、telegraf
、およびjimp
モジュールの詳細については、 Pexels API 、 telegraf 、jimp[のドキュメントを参照してください。 X160X]。