In this article, I want to introduce a new Urban Bot library that adapts React for writing chat bots. Below I will tell you why this library was born, what advantages it provides, and how to write your first chatbot.
A chatbot is most often a separate chat in a messenger, in which you communicate not with a person, but with a program. It can send messages in the form of text, images, buttons and many other UI elements and respond to messages from users. Modern chat bots are full-fledged UI applications inside instant messengers.
- , http bot.on('message', callback)
, , Urban Bot - — . , Urban Bot, Telegram, c -, GitHub.
, - UI . 2020 UI ? , JavaScript React. - API . , -, , , , .
Urban Bot. Text , . , - "Hello, world!".
import React from 'react';
import { Text } from '@urban-bot/core';
function App() {
return (
<Text>
Hello, world!
</Text>
);
}
:
import React from 'react';
import { Image } from '@urban-bot/core';
function App() {
const imageByURL = 'https://some-link.com/image.jpg';
return <Image file={imageByURL} />;
}
Urban Bot , , File, ButtonGroup , . , , 1 <Text simulateTyping={1000}>
.
, . Urban Bot React Hooks.
, useText.
import React from 'react';
import { Text, useText } from '@urban-bot/core';
function App() {
useText(({ text }) => {
console.log(` ${text}`);
});
return (
<Text>
Hello, world!
</Text>
);
}
Urban Bot . , useImage, , useFile .. . , ..
, , . , .
React useState. , . React.useState
, , , . text
"" Text
. useText
, text
setText
. setText
React Echo , .
import React from 'react';
import { Text, useText } from '@urban-bot/core';
function Echo() {
const [text, setText] = React.useState('!');
useText(({ text }) => {
setText(text);
});
return (
<Text>
{text}
</Text>
);
}
, . ButtonGroup
Button
. , count +1 -1 ButtonGroup
title. isNewMessageEveryRender
false
, , .
import React from 'react';
import { ButtonGroup, Button } from '@urban-bot/core';
function Counter() {
const [count, setCount] = React.useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<ButtonGroup title={count} isNewMessageEveryRender={false}>
<Button onClick={increment}>+1</Button>
<Button onClick={decrement}>-1</Button>
</ButtonGroup>
);
}
. , -, . Router . — .
, "/echo" — Echo
, "/counter" — Counter
. path
regexp.
import React from 'react';
import { Router, Route } from '@urban-bot/core';
import { Echo } from './Echo';
import { Counter } from './Counter';
function App() {
return (
<Router>
<Route path="/echo">
<Echo />
</Route>
<Route path="/counter">
<Counter />
</Route>
</Router>
);
}
, .
, , , , , , - SPA .
Urban Bot HTML . <b>
, <i>
, <s>
, <br />
, .
const someCode = `
function sum2() {
return 2 + 2;
}
if (sum2() !== 4) {
console.log('WTF');
}`;
<Text>
Usual text
<br />
<b>Bold text</b>
<br />
<i>Italic text</i>
<br />
<u>Underscore text</u>
<br />
<s>Strikethrough text</s>
<br />
<q>quote</q>
<br />
<b>
Bold and <s>Strikethrough text</s>
</b>
<br />
<code >Code 2 + 2</code >
<br />
<pre>{someCode}</pre>
<br />
<a href="https://github.com/urban-bot/urban-bot">External link</a>
</Text>
- , - , . Urban Bot Dialog
, .
. , , , callback onFinish
. callback onNext
.
import React from 'react';
import { Dialog, DialogStep, Text } from '@urban-bot/core';
function FlatDialogExample() {
return (
<Dialog onFinish={(answers) => console.log(answers)}>
<DialogStep
content={<Text>, ?</Text>}
id="name"
onNext={(name) => console.log(name)}
>
<DialogStep
content={<Text>C ?</Text>}
id="age"
>
<DialogStep
content={<Text> ?</Text>}
id="city"
/>
</DialogStep>
</DialogStep>
</Dialog>
);
}
function FlatDialogExample() {
return (
<Dialog>
<DialogStep content={<Text>, ?</Text>}>
{(name) => (
<DialogStep
content={<Text>{`${name}, c ?`}</Text>}
/>
)}
</DialogStep>
</Dialog>
);
}
.
function FlatDialogExample() {
return (
<Dialog onFinish={(answers) => console.log(answers)}>
<DialogStep
content={<Text>, ?</Text>}
id="name"
validation={{
isValid: (answer) => answer !== '',
errorText: ' .'
}}
>
// ...
</DialogStep>
</Dialog>
);
}
, . .
import React from 'react';
import { Dialog, DialogStep, Text, ButtonGroup, Button } from '@urban-bot/core';
function TreeDialogExample() {
return (
<Dialog>
<DialogStep
content={
<ButtonGroup title=", ?">
<Button id="hat"></Button>
<Button id="glasses"></Button>
</ButtonGroup>
}
>
<DialogStep
match="hat"
content={
<ButtonGroup title=" ?">
<Button id="m">S</Button>
<Button id="s">M</Button>
<Button id="l">L</Button>
</ButtonGroup>
}
/>
<DialogStep
match="glasses"
content={
<ButtonGroup title=" ?">
<Button id="black"></Button>
<Button id="white"></Button>
</ButtonGroup>
}
/>
</DialogStep>
</Dialog>
);
}
? React . React useState
React Context. : Redux (), MobX (), Apollo , React, React Web React Native , Urban Bot React, .
Urban Bot , , , React , . Urban Bot , , React , .
Urban Bot . , , -, .
function Counter() {
const [count, setCount] = React.useState(0);
const increment = () => setCount(count + 1);
const decrement = () => setCount(count - 1);
return (
<ButtonGroup title={count} isNewMessageEveryRender={false}>
<Button onClick={increment}>+1</Button>
<Button onClick={decrement}>-1</Button>
</ButtonGroup>
);
}
, , .
function Counter() {
const [count, setCount] = useGlobalCount();
// ...
}
, , , .. - , chat
from
.
import React from 'react';
import { Text, useText, useBotContext } from '@urban-bot/core';
function UserId() {
const { chat } = useBotContext();
useText(({ from }) => console.log(` ${from.username}`));
return <Text> id {chat.id}</Text>;
}
Urban Bot TypeScript, , TypeScript, .
Urban Bot, . @urban-bot/core
, -, . Telegram, Slack, Facebook. , , - API. , Urban Bot , Viber, Discord https://t.me/urbanbotjs, , .
. , . , .
, App
Telegram. UrbanBotTelegram
@urban-bot/telegram. render
@urban-bot/core
ReactDOM.render
Root
. UrbanBotTelegram
Telegram, isPolling, , . Root
, , , render, .
import React from 'react';
import { render, Root } from '@urban-bot/core';
import { UrbanBotTelegram } from '@urban-bot/telegram';
import { App } from './App';
const urbanBotTelegram = new UrbanBotTelegram({
token: 'telegramToken',
isPolling: true,
});
render(
<Root bot={urbanBotTelegram}>
<App />
</Root>
);
, , Telegram.
// ...
import { UrbanBotSlack } from '@urban-bot/slack';
// ...
render(
<Root bot={urbanBotTelegram}>
<App />
</Root>
);
const urbanBotSlack = new UrbanBotSlack({
signingSecret: 'slackSigningSecret',
token: 'slackToken',
});
render(
<Root bot={urbanBotSlack}>
<App />
</Root>
);
API
Urban Bot - . API? UrbanBot* API . Telegram.
bot
useBotContext. bot
client
type
c . client
node-telegram-bot-api . client
, , .
import React from 'react';
import { useText, useBotContext } from '@urban-bot/core';
function SomeComponent() {
const { bot } = useBotContext();
useText(({ text, chat, from }) => {
if (text.includes('***')) {
bot.client.kickChatMember(chat.id, from.id);
}
});
// ...
}
API. , bot.type
.
import { useBotContext } from '@urban-bot/core';
import { UrbanBotTelegram } from '@urban-bot/telegram';
import { UrbanBotSlack } from '@urban-bot/slack';
function SomeComponent() {
const { bot } = useBotContext();
if (bot.type === UrbanBotTelegram.type) {
// telegram api
bot.client.kickChatMember(/* ... */);
}
if (bot.type === UrbanBotSlack.type) {
// slack api
bot.client.conversations.kick(/* ... */);
}
// ...
}
?
Urban Bot , - , create-rect-app
. , Urban Bot —
TypeScript
npx create-urban-bot my-app
JavaScript
npx create-urban-bot my-app --template js
Urban Bot , — . , React, - , ui-kit, UI React, web mobile.
-, Urban Bot, . , React, - 5 . , , Telegram, , .