15분이면 모든 질문에 답할 수 있는 텔레그램 봇을 만들 수 있습니다.
10816 단어 nodetypescriptjavascripttelegram
소개
지난 기사에서 우리는 ,
좋은 반응으로 인해 저는 15분의 다른 도전을 가져오기로 결정했습니다. 오늘은 Genius라는 텔레그램 봇입니다.
규칙:
- interact with the system by telegram chat (Obviously)
- Searches must be carried out using wikipedia
- The robot must be able to change its response if it is not satisfactory to the user
시작하자
프로젝트 만들기
프로젝트에 폴더를 만들고 터미널에서 다음 명령을 실행합니다.
npm init -y && npx ts-init
tsconfig.json
파일이 다음과 같은지 확인하십시오.{
"compilerOptions": {
"lib": [
"es6",
"DOM"
],
"alwaysStrict": true,
"strictNullChecks": true,
"noImplicitAny": true,
"esModuleInterop": true,
"resolveJsonModule": true
},
"files": [
"src/index.ts"
]
}
패키지를 받자
npm i node-telegram-bot-api --save && npm i @types/node-telegram-bot-api -D
node-telegram-bot-api은 Telegram Bot API를 추상화하고 우리의 삶을 더 쉽게 만들어주는 놀라운 라이브러리입니다. npm i wikipedia --save
Wikipedia은 위키 끝점을 추상화하는 간단한 라이브러리입니다. 봇 만들기
/newBot
코딩하자
우선 사용할 라이브러리를 가져와야 하므로
src/index.ts
라는 파일을 만듭니다.import telegram from 'node-telegram-bot-api';
import wikipedia from 'wikipedia';
const TELEGRAM_KEY = "YOUR-API-KEY-HERE";
YOUR-API-KEY-HERE가 쓰여진 위치를 로봇 키로 바꾸는 것을 잊지 마십시오.
일부 상호 작용 만들기
이 코드를
src/index.ts
안에 붙여넣으세요....
const Bot = new telegram(TELEGRAM_KEY, {polling: true});
Bot.onText(/\/start/, async (msg) => {
if(!msg.from) return Bot.sendMessage(msg.chat.id, 'I not accept you!');
Bot.sendMessage(msg.chat.id, 'Wellcome to GeniusAnswer, ask me something');
});
사용자가 봇을 시작하면 사용자에게 질문을 요청하는 메시지를 보냅니다.
주요 기능
이 코드를
src/index.ts
안에 붙여넣으세요....
const wikisearch = async (topic: string, pageIndex: number) => {
const search = await wikipedia.search(topic);
if(pageIndex > search.results.length) throw new Error('Invalid page index');
const page = await wikipedia.page(search.results[pageIndex].title);
const summary = await page.summary();
return {text: summary.extract, pageIndex: 0, pageLength: search.results.length};
};
Bot.on("text", async (msg) => {
if (!msg.from) return Bot.sendMessage(msg.chat.id, "I not accept you!");
if (!msg.text) return Bot.sendMessage(msg.chat.id, "Invalid message");
if (msg.text[0] === "/") return;
Bot.sendMessage(msg.chat.id, `Searching for ${msg.text} ...`);
const search = await wikisearch(msg.text, 0);
console.log(search);
let options_button = {};
if (search.pageIndex < search.pageLength) {
options_button = {
reply_markup: {
inline_keyboard: [
[
{
text: "Next Answer ->",
callback_data: JSON.stringify({ topic: msg.text, pageIndex: 1 }),
},
],
],
},
};
}
return Bot.sendMessage(
msg.chat.id,
`${search.text} \n Answer ${search.pageIndex + 1}/${search.pageLength}`,
options_button
);
});
});
여기서는 Wikipedia에서 검색하고 이 결과의 인덱스를 반환할 수 있는 검색 함수만 만듭니다. 이 질문에 대해 다른 결과가 필요한 경우 함수에 대한 다른 인덱스만 전달하면 됩니다.
다음 기능에서 봇으로 보내는 문자 메시지를 수신하고 결과에 검색 색인을 변경할 수 있는 버튼을 넣습니다.
콜백 함수
이 코드를
src/index.ts
안에 붙여넣으세요....
Bot.on("callback_query", async (callback) => {
if (!callback.data || !callback.message) return;
console.log(callback.data);
const data = JSON.parse(callback.data) as {
topic: string;
pageIndex: number;
};
try {
const search = await wikisearch(data.topic, data.pageIndex);
console.log(search);
let options_button = {};
let inline_keyboard_buttons = [];
if (search.pageIndex + 1 < search.pageLength) {
inline_keyboard_buttons.unshift({
text: "Next Answer ->",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex + 1,
}),
});
if (search.pageIndex > 0) {
inline_keyboard_buttons.unshift({
text: "<- Previous Answer",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex - 1,
}),
});
}
} else if (search.pageIndex + 1 === search.pageLength) {
inline_keyboard_buttons.unshift({
text: "<- Previous Answer",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex - 1,
}),
});
}
if (inline_keyboard_buttons.length > 0) {
options_button = {
reply_markup: {
inline_keyboard: [inline_keyboard_buttons],
},
};
}
return Bot.editMessageText(
`${search.text} \n Answer ${search.pageIndex + 1}/${search.pageLength}`,
{
chat_id: callback.message.chat.id,
message_id: callback.message.message_id,
...options_button,
}
);
} catch (error) {
return Bot.editMessageText(
"Sorry, an error seems to have happened, please try again later",
{
chat_id: callback.message.chat.id,
message_id: callback.message.message_id,
}
);
}
});
콜백 함수가 매우 길지만 이해하기 쉽습니다. 검색 주제를 캡처하고 인덱스를 변경합니다. 다음 또는 이전 페이지가 있는지 여부에 따라 메시지에 해당 버튼을 추가합니다.
이제 코드는 다음과 같아야 합니다.
import telegram from "node-telegram-bot-api";
import wikipedia from "wikipedia";
const TELEGRAM_KEY = "YOUR-TELEGRAM-KEY-HERE";
const Bot = new telegram(TELEGRAM_KEY, { polling: true });
Bot.onText(/\/start/, (msg) => {
if (!msg.from) return Bot.sendMessage(msg.chat.id, "I not accept you!");
Bot.sendMessage(msg.chat.id, "Wellcome to GeniusAnswer, ask me something");
});
const wikisearch = async (topic: string, pageIndex: number) => {
const search = await wikipedia.search(topic);
if (pageIndex > search.results.length) throw new Error("Invalid page index");
const page = await wikipedia.page(search.results[pageIndex].title);
const summary = await page.summary();
return {
text: summary.extract,
pageIndex: pageIndex,
pageLength: search.results.length,
};
};
Bot.on("text", async (msg) => {
if (!msg.from) return Bot.sendMessage(msg.chat.id, "I not accept you!");
if (!msg.text) return Bot.sendMessage(msg.chat.id, "Invalid message");
if (msg.text[0] === "/") return;
Bot.sendMessage(msg.chat.id, `Searching for ${msg.text} ...`);
const search = await wikisearch(msg.text, 0);
console.log(search);
let options_button = {};
if (search.pageIndex < search.pageLength) {
options_button = {
reply_markup: {
inline_keyboard: [
[
{
text: "Next Answer ->",
callback_data: JSON.stringify({ topic: msg.text, pageIndex: 1 }),
},
],
],
},
};
}
return Bot.sendMessage(
msg.chat.id,
`${search.text} \n Answer ${search.pageIndex + 1}/${search.pageLength}`,
options_button
);
});
Bot.on("callback_query", async (callback) => {
if (!callback.data || !callback.message) return;
console.log(callback.data);
const data = JSON.parse(callback.data) as {
topic: string;
pageIndex: number;
};
try {
const search = await wikisearch(data.topic, data.pageIndex);
console.log(search);
let options_button = {};
let inline_keyboard_buttons = [];
if (search.pageIndex + 1 < search.pageLength) {
inline_keyboard_buttons.unshift({
text: "Next Answer ->",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex + 1,
}),
});
if (search.pageIndex > 0) {
inline_keyboard_buttons.unshift({
text: "<- Previous Answer",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex - 1,
}),
});
}
} else if (search.pageIndex + 1 === search.pageLength) {
inline_keyboard_buttons.unshift({
text: "<- Previous Answer",
callback_data: JSON.stringify({
topic: data.topic,
pageIndex: search.pageIndex - 1,
}),
});
}
if (inline_keyboard_buttons.length > 0) {
options_button = {
reply_markup: {
inline_keyboard: [inline_keyboard_buttons],
},
};
}
return Bot.editMessageText(
`${search.text} \n Answer ${search.pageIndex + 1}/${search.pageLength}`,
{
chat_id: callback.message.chat.id,
message_id: callback.message.message_id,
...options_button,
}
);
} catch (error) {
return Bot.editMessageText(
"Sorry, an error seems to have happened, please try again later",
{
chat_id: callback.message.chat.id,
message_id: callback.message.message_id,
}
);
}
});
이제 코드가 완성되었습니다. 테스트해 볼까요?
터미널에서
npm run ts
를 실행하고 텔레그램을 엽니다.봇 이름(이 문서의 시작 부분에서 만든 것과 동일하며 일반적으로 _bot으로 끝남)을 검색하고 START를 누릅니다.
너 자신을 즐겨!
이 로봇의 응답 시간을 최적화하는 몇 가지 방법이 있습니다. 관심이 있으시면 나중에 다른 기사에서 보여줄 수 있지만 로봇 아이디어를 좋아하는 사람들에게는 이것이 흥미로운 도전이라고 생각합니다. 댓글에 남겨주세요. 당신의 솔루션과 아이디어
Reference
이 문제에 관하여(15분이면 모든 질문에 답할 수 있는 텔레그램 봇을 만들 수 있습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/leonardbonetti/15-minutes-to-create-a-telegram-bot-that-can-answer-any-question-2p26텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)