Urban Bot ou comment écrire des robots de discussion pour Telegram, Slack, Facebook ... sur React.js

image



Dans cet article, je souhaite vous présenter la nouvelle bibliothèque Urban Bot qui adapte React pour écrire des robots de discussion. Ci-dessous, je vais vous dire pourquoi cette bibliothèque est née, quels avantages elle offre et comment écrire votre premier chatbot.



- — , , . , , UI . - — UI .

- , 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>
    );
}


, .



image



, , , , , , - 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>
    );
}


render-props .



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, .



Telegram .



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


, , .env , . .





Urban Bot , — . , React, - , ui-kit, UI React, web mobile.



-, Urban Bot, . , React, - 5 . , , Telegram, , .







Github

Telegram

- Telegram, .

Todo List - Telegram React.js




All Articles