Node.js、Telegraf、Jimp、およびPexelsを使用してTelegramQuotesGeneratorボットを構築する方法
序章
このチュートリアルでは、 Node.js 、 telegraf 、 jimp 、および Pexels APIを使用して、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
ファイル。 ファイル内の内容を強調表示されたコードに置き換えます。
{
"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
追加したプロパティ script
名前付き start
、これにより、アプリケーションの起動時に実行されるはずのコマンドを設定できます。 あなたが電話したら script
コマンド nodemon
を実行します main.js
次のステップで作成するファイル。
設定が定義されました package.json
ファイル、環境変数を保存するファイルを作成します。 ターミナルで、という名前のファイルを作成します .env
:
touch .env
あなたの中で .env
ファイルには、TelegramボットトークンとPexelsAPIキーを保存します。 Telegram Botトークンを使用すると、Telegramボットと対話できます。 Pexels APIキーを使用すると、PexelsAPIを操作できます。 後のステップで環境変数を保存します。
今回は使用します npm
依存関係をインストールするには telegraf
, dotenv
, pexels
, jimp
、 と uuid
. また、 --save
依存関係を保存するためのフラグ。 ターミナルで、次のコマンドを実行します。
- npm install telegraf dotenv pexels jimp uuid --save
このコマンドでは、以下をインストールしました。
- telegraf :JavaScriptまたはTypeScriptを使用して独自のTelegramボットを開発するのに役立つライブラリ。 これを使用してボットを構築します。
- dotenv :環境変数をからロードするゼロ依存モジュール
.env
ファイルにprocess.env
. このモジュールを使用して、ボットトークンとPexelsAPIキーを.env
作成したファイル。 - 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
:
BOT_TOKEN = "Your bot token"
これで、ボットトークンが .env
ファイル、PexelsAPIキーを取得する時が来ました。
Pexels に移動し、Pexelsアカウントにログインします。 クリックしてください画像と動画のAPI タブをクリックして、新しいAPIキーを作成します。
APIキーをコピーして、 .env
ファイル:
- nano .env
APIキーをという名前の変数に保存します PEXELS_API_KEY
. 君の .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
ファイルに次のコードを追加して、使用するライブラリをインポートします。
const { Telegraf } = require('telegraf')
const { v4: uuidV4 } = require('uuid')
require('dotenv').config()
let factGenerator = require('./factGenerator')
このコードブロックでは、 telegraf
、 uuid
、 dotenv
モジュール、およびという名前のファイル factGenerator.js
. あなたは使用しようとしています telegraf
ボットを起動および管理するためのモジュール、 uuid
画像の一意のファイル名を生成するモジュール、および dotenv
TelegramボットトークンとPexelsAPIキーを取得するモジュール .env
ファイル。 The factGenerator.js
ファイルは、Pexelsからランダムな動物の画像を取得し、動物に関する事実を挿入し、ユーザーに送信された後に画像を削除するために使用されます。 このファイルは次のセクションで作成します。
下 require
ステートメントに次のコードを追加して、ボットのインスタンスを作成します。
. . .
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_TOKEN
そのBotFatherが送信し、新しいボットインスタンスを作成し、それをという変数に割り当てました。 bot
. 新しいボットインスタンスを作成した後、次のコマンドリスナーを追加しました /start
指図。 このコマンドは、ユーザーとボットの間の会話を開始する役割を果たします。 ユーザーが以下を含むメッセージを送信すると /start
ボットは、ユーザーに使用するように求めるメッセージで応答します。 /fact
新しい事実を受け取るコマンド。
これで、チャットボットとの対話を開始するコマンドハンドラーが作成されました。 それでは、ファクトを生成するためのコマンドハンドラーを作成しましょう。 下 .start()
コマンド、次のコードを追加します。
. . .
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ユーザーインターフェイスからトリガーされると、ボットはユーザーにメッセージを送信します。 The uuid
モジュールは、画像の名前とパスを生成するために使用されます。 画像はに保存されます /temp
ステップ1で作成したディレクトリ。 その後、画像パスはという名前のメソッドに渡されます generateImage()
で定義します factGenerator.js
動物に関する事実を含む画像を生成するファイル。 画像が生成されると、画像がユーザーに送信されます。 次に、画像パスがという名前のメソッドに渡されます deleteFile
の中に factGenerator.js
画像を削除するファイル。 最後に、 bot.launch()
方法。
The 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つのデータソースに保存します。 The factGenerator.js
ファイルには、ファイルから動物に関するランダムな事実を取得し、Pexelsから画像を取得し、使用するために必要なコードが含まれます。 jimp
取得した画像にファクトを書き込み、画像を削除します。
プロジェクトのルートディレクトリで、を作成して開きます facts.js
お好みのテキストエディタを使用したファイル:
- nano 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
ファイルに、動物の画像を作成するためのロジックを構築するために使用する依存関係に必要な次のコードを追加します。
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
ステートメントに、次のコードを追加して画像を生成します。
. . .
async function generateImage(imagePath) {
let fact = randomFact()
let photo = await getRandomImage(fact.animal)
await editImage(photo, imagePath, fact.fact)
}
このコードブロックでは、という名前の関数を作成しました generateImage()
. この関数は、ファイルディレクトリ内のPexelイメージのパスを引数として取ります。 この関数が呼び出されると、 randomFact()
が呼び出され、返された値がという名前の変数に格納されます fact
. The randomFact()
関数はランダムにオブジェクトを選択します facts.js
ファイル。 オブジェクトを受け取った後、そのプロパティ animal
名前の付いた関数に渡されます getRandomImage()
. The getRandomImage()
関数はを使用します pexels
渡された動物の名前を含む画像を検索し、ランダムな画像を選択するモジュール。 返される値は、という名前の変数に格納されます photo
. 最後に、 photo
, imagePath
、 そしてその fact
からのプロパティ facts.js
ファイルはという名前の関数に渡されます editImage()
. The editImage()
関数はを使用します jimp
ランダムな事実をランダムな画像に挿入し、編集した画像を imagePath
.
ここでは、送信時に呼び出される関数を作成しました /fact
ボットへのスラッシュコマンド。 次に、関数を作成します getRandomImage()
と editImage()
ランダムな画像の選択と編集の背後にあるロジックを構築します。
下 generateImage()
関数、ランダム化ロジックを設定するために次のコードを追加します。
. . .
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()
. The randomFact()
関数はランダムを選択します fact
の中に facts.js
を呼び出すことによってファイル randomInteger()
関数であり、このオブジェクトを返します。 The randomInteger()
関数は、0の間隔のランダムな整数とファクトの数を返します。 facts.js
ファイル。
ランダムなファクトとランダムな整数を返す関数を定義したので、Pexelsからランダムな画像を取得する関数を作成する必要があります。 下 randomInteger()
関数、ランダムな画像を取得するには、次のコードを追加します。
. . .
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
オブジェクトはを使用して作成されます createClient()
からのメソッドオブジェクト pexels
モジュールと、に保存されているPexelsAPIキー .env
ファイル。 動物の名前は、という変数に格納されます query
、 そうして client
オブジェクトは、の値を含む画像を検索するために使用されます query
. 画像が見つかると、ランダムな画像が選択されます randomInteger()
関数。 最後に、ランダムな画像がに返されます generateImage()
あなたの方法 main.js
ファイル。
あなたと getRandomImage()
機能が適切に機能するため、選択した画像は、Telegramボットに送信する前にテキストオーバーレイを使用する必要があります。 下 getRandomImage()
関数、オーバーレイを設定するために次のコードを追加します。
. . .
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から取得されます。 その後、 read()
の方法 jimp
画像の読み込みに使用されます。 画像がロードされ、名前の付いた変数に格納されたら animalImage
、画像の幅と高さが取得され、変数に格納されます animalImageWidth
と animalImageHeight
それぞれ。 変数 imgDarkener
の新しいインスタンスを格納します Jimp()
画像を暗くします。 The opacity()
の方法 jimp
設定に使用されます imgDarkener
の不透明度を50%にします。 最後に、 composite()
の方法 jimp
内容を入れるために使用されます imgDarkener
の画像の上に animalImage
. これは見返りに画像を作成します animalImage
に保存されているテキストを追加する前に暗くします fact
変数を入力し、画像上にテキストを表示します。
注: Jimpはデフォルトで、という名前のメソッドを提供します color()
これにより、画像の色調レベルを調整できます。 このチュートリアルでは、カスタムトーンアジャスターを次のように記述します。 color()
メソッドは、ここで必要な精度を提供しません。
の下部に try
内部のブロック editImage()
関数、次のコードを追加します。
. . .
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
. その後、あなたは loadFont()
の方法 jimp
フォントをロードし、フォントをという名前の変数に格納します font
. フォントの色は白、タイプはsans-serif(SANS
)、サイズは16です。 最後に、 print()
の方法 jimp
挿入するには fact
の中に animalImage
、 そしてその write()
保存する方法 animalImage
の中に imagePath
.
画像の編集を担当する関数を作成したので、ユーザーに画像を送信した後、ファイル構造から画像を削除する関数が必要になります。 あなたの下に editImage()
関数、次のコードを追加します。
. . .
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
ファイルは次のようになります。
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のドキュメントを参照してください。