サポートチャット管理ダッシュボードを作成します


In this tutorial, we'll build a chat app with a dashboard that allows an admin user to switch between one-on-one customer chat channels in the same window.



忙しい顧客サポートの代表として、あなたは、新しいウィンドウでチャットを開き、複数のブラウザのタブを介してサイクルを強制的に開いているチケットのトラックを失うことによって発生するチャットアプリケーションで立ち往生する必要はありません.我々はこのポストでビルドするアプリは、彼らが(iMessageと同じように)来て、新しいメッセージをボルトでコンパクトなダッシュボードのすべての顧客チャットが表示され、サポート担当者が迅速かつ容易にチャットの間に移動することができます.さらに、これは数時間ではなく、時間がかかります.

要件

  • node.js
  • React
  • 無料のStream 試用口座
  • 基礎知識React Hooks and Express .
  • 背景


    ストリームチャットは、このアプリのためだけでなく、いくつかの基本的なボックススタイリングのチャットインフラストラクチャを提供します.トピックはエクスプレスJSを使用してカバーされ、反応するが、方法論は、ほとんどの言語やフレームワークに移植することができます.
    このポストは、あなたを案内しますGit Repository here .

    ストリームの設定


    無料ストリームトライアルアカウントが必要になりますgrab yours here . 一度サインアップした、あなたの新しいアプリを作成するStream dashboard .
  • ダッシュボード用のNavbarリンク
  • ダッシュボードから、'作成アプリケーション'ボタンで新しいアプリを作成します
  • あなたのアプリの名前を選択し、'開発'モードを選択
  • これはAPIキーと秘密を生成します.env ファイルを一度に.

  • 無効にするストリームのチェックとパーミッション


    ストリームはデフォルトで認証チェックとパーミッションチェックを提供します.これらはどんな生産環境にも役立つでしょうが、この場合はそれらを無効にします.以下に
  • あなたのストリームダッシュボードでは、あなたのアプリケーションを選択します.'チャット' Navbarドロップダウンをクリックし、'概要'を選択
  • スクロールダウンして無効にするチェックを無効にします.

  • . env設定


    The Git Repo ファイルを含むbackend タイトル.env.example . あなたのストリームAPIキーとストリーム秘密をここに加えてください.env .
    // backend/.env.example:1
    NODE_ENV=development
    PORT=8080
    
    STREAM_API_KEY= your Stream API key here
    STREAM_API_SECRET= your Stream API secret here
    

    スピンアップ


    あなたのアプリケーションを実行する準備が整いました.アプリはAに分割されますfrontend フォルダ作成stream-chat-reactbackend フォルダ作成npm express-generator .
    あなたのマシン上でアプリケーションを起動するにはnpm install and npm run start 両方ともfrontend and backend フォルダ.一度実行すると、移動http://localhost:3000 見るfrontend . 今、我々はどのようにこのアプリの作品に飛び込むことができます.

    ルータ


    フロントエンドはAdmin コンポーネントCustomer コンポーネント.それぞれの独自のログインページとチャットウィンドウがあります.ここではRouter 二つを区別する.
    // frontend/src/index.js:9
    ReactDOM.render(
      <React.StrictMode>
        <BrowserRouter>
          <Switch>
            <Route path="/" exact={true}>
              <Customer />
            </Route>
            <Route path="/admin" exact={true}>
              <Admin />
            </Route>
          </Switch>
        </BrowserRouter>
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    顧客ログインを表示するにはlocalhost:3000/ . 管理ログインを表示するにはlocalhost:3000/admin .

    カスタマーログイン


    のログイン部分を調べましょうCustomer コンポーネント.
    // frontend/src/Customer.js:105
    return (
      <div className="App container">
        <form className="card" onSubmit={register}>
          <label>First Name</label>
          <input
            type="text"
            value={firstName}
            onChange={(e) => setFirstName(e.target.value)}
            placeholder="first name"
            required
          />
          <label>Last Name</label>
          <input
            type="text"
            value={lastName}
            onChange={(e) => setLastName(e.target.value)}
            placeholder="last name"
            required
          />
          <label>Email</label>
          <input
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            placeholder="email"
            required
          />
          <button type="submit">
            Start chat
          </button>
        </form>
      </div>
    );
    
    上記のスニペットは、次のことを返します.

    この単純なログインフォームはfirstName , lastName , and email . これらは、register 関数.レジスタ機能の前半を覗いてみましょうPOST バックエンドへ
    // frontend/src/Customer.js:29
    e.preventDefault();
    const response = await fetch('http://localhost:8080/customer-login', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        firstName,
        lastName,
        email,
      }),
    });
    
    私は、この要求をどんな図書館なしでも書くことを選びました.私はaxios ライブラリを簡素化を探している場合.
    次に、どのようにバックエンドとどのように登録を処理するかを見てみましょう.

    カスタマーログイン


    まず、バックエンドはserverSideClient , あなたのユニークなストリームAPIキーと秘密で認証されます.
    // backend/routes/api.js:5
    const streamApiKey = process.env.STREAM_API_KEY;
    const streamApiSecret = process.env.STREAM_API_SECRET;
    const serverSideClient = new StreamChat(streamApiKey, streamApiSecret);
    
    次は/customer-login エンドポイントは、顧客の入力を受け入れ、チャットを登録します.以下にプロセスフローを示します:
  • フロントエンドからの顧客入力の正規化
  • 顧客のトークンを生成する
  • チャットチャンネルを開く
  • メンバーをチャンネルに加える
  • このデータをフロントエンドに戻す
  • ストリームライブラリがどのようにこのプロセスのためのワークホースであるかに注意してください.createToken , .updateUser , .channel , and .addMembers .
    // backend/routes/index.js:10
    router.post('/customer-login', async (req, res) => {
      try {
        const firstName = req.body.firstName.replace(/\s/g, '_');
        const lastName = req.body.lastName.replace(/\s/g, '_');
        const username = `${firstName}${lastName}`.toLowerCase();
    
        const customerToken = serverSideClient.createToken(username);
        await serverSideClient.updateUser(
          {
            id: username,
            name: firstName
          },
          customerToken
        );
    
        const channel = serverSideClient.channel('messaging', username, {
          name: `Chat with ${username}`,
          created_by: { id: 'admin' },
          members: [username, 'admin']
        });
    
        await channel.create();
        await channel.addMembers([username, 'admin']);
    
        res.status(200).json({
          customerId: username,
          channelId: username,
          customerToken,
          streamApiKey,
        });
    
      } catch (err) {
        console.error(err);
        res.status(500).json({ error: err.message });
      }
    });
    
    上記で使用されるストリームメソッドについてのいくつかの有用な注意
  • .createToken 引数のユーザー名を取得し、チャット内の各参加者の一意のトークンを生成します.
  • .updateUser ユーザが使用するオブジェクトを取り込むid を送らなければならないname を適用できます.このメソッドはユーザのトークンを必要とします.
  • .channel アクセプト(チャネルの種類、チャネルID、オプションオブジェクト).の配列を指定するmembers , ユーザIDが指定されたものに対してチャネルアクセスを制限します.
  • 次に、フロントエンドがバックエンド応答を受け取る方法をチェックします.

    チャット初期化(フロントエンド)


    フロントエンドの後半を探検しましょうregistration ファンクションCustomer.js :
    // frontend/src/Customer.js:43
    try {
      //...
    
      const { customerId, customerToken, channelId, streamApiKey } = await response.json();
      chatClient = new StreamChat(streamApiKey);
    
      await chatClient.setUser(
        {
          id: customerId,
          name: firstName,
        },
        customerToken,
      );
    
      const channel = chatClient.channel('messaging', channelId, {
        name: `Chat with ${customerId}`
      });
    
      await channel.watch;
      setChannel(channel);
    
    } catch (e) {
      console.error(e, e.error);
    }
    
    バックエンドの応答は破壊される.次の手順では、バックエンドからチャットセットアップをミラーリングします.
  • ユーザを設定する
  • フロントエンドのチャネルを設定します
  • チャンネルを見てください、それで、ユーザーのブラウザーがチャンネルで起こるすべての出来事を受けます
  • setChannel(channel) は、チャットをレンダリングする際に、後でチャンネル状態を使用できるように呼び出されます
  • 顧客チャット


    これでchannel が確立されると、顧客チャットは次のコードブロックで返されます.
    // frontend/src/Customer.js:66
    if (channel) {
      return (
        <Chat client={chatClient} theme="commerce light">
          <Channel channel={channel}>
            <Window>
              <div className="stream-header">
                <div className="str-header-left">
                  <p className="stream-header-left-title">
                    Customer Support Chat
                  </p>
                </div>
                <div className="str-chat__header-livestream-right">
                  Second National Bank
                </div>
              </div>
              <MessageList
                typingIndicator={TypingIndicator}
                Message={MessageCommerce}
              />
              <MessageInput Input={MessageInputFlat} focus />
            </Window>
          </Channel>
        </Chat>
      );
    } else {
      // ...
    }
    
    ここで、ストリームは、チャットを構築するために必要なすべてのコンポーネントを提供します.ヘッダーはオプションの包含です、しかし、それは我々にいくつかのビルトインデータストリーム申し込みで遊ぶ機会を与えます.

    ⭐️Good to know: Stream offers loads of convenient channel data we can use anywhere in our apps. We can replace the Second National Bank header with something like: Welcome, {client.user.name}, to render:



    The <Chat /> コンポーネントのいくつかのハンサムボックスのテーマがあります.この例では、使用しますcommerce light . Here's a list 利用できるテーマの.
    作成したチャンネルは<Channel /> コンポーネント.The <MessageList /> and <MessageInput /> 簡単にもcustomized . それは顧客側に必要なことですチェックアウトしましょうAdmin コンポーネント.

    管理ログイン


    管理者ログインページは、顧客と同じ手順を模倣しますが、Admin Id フォーム入力で.以下にフォームを示します:
    // frontend/src/Admin.js:81
    return (
      <div className="App container">
        <form className="card" onSubmit={register}>
          <label>Admin Id</label>
          <input
            type="text"
            value={adminId}
            onChange={(e) => setAdminId(e.target.value)}
            placeholder="Enter your admin ID"
            required
          />
          <button type="submit">
            Start chat
          </button>
        </form>
      </div>
    );
    
    そしてここに登録機能がありますPOST 'とadminId , しかし、同じチャンネルセットアップに従います.
    // frontend/src/Admin.js:23
    const register = async (e) => {
      try {
        e.preventDefault();
        const response = await fetch('http://localhost:8080/admin-login', {
          method: 'POST',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            adminId,
          }),
        });
    
        const { adminToken, streamApiKey, adminName } = await response.json();
        chatClient = new StreamChat(streamApiKey);
    
        await chatClient.setUser(
          {
            id: adminName,
            name: 'Administrator'
          },
          adminToken,
        );
    
        const channel = chatClient.channel('messaging', 'livechat');
    
        await channel.watch();
        setChannel(channel);
    
      } catch (e) {
        console.error(e);
      }
    };
    
    これは/customer-login エンドポイント.これは、トークンを作成し、クライアントを初期化し、ユーザーを設定し、一般的なチャネルを開きます.新しい顧客がチャットを開始するように、チャネルのリストが自動的に設定されます.

    管理ダッシュボードをレンダリングする


    以下に、管理ダッシュボードの外観を示します.

    顧客と管理者登録の主な違いは、レンダリングされたストリームコンポーネントにあります.
    // frontend/src/Admin.js:59
    return (
      <Chat client={chatClient} theme={"messaging light"}>
        <ChannelList
          sort={{ last_message_at: -1 }}
          Preview={ChannelPreviewMessenger}
          onSelect={(channel) => { setChannel(channel); }}
        />
        <Channel>
          <Window>
            <ChannelHeader />
            <MessageList />
            <MessageInput focus />
          </Window>
          <Thread />
        </Channel>
      </Chat >
    );
    
    注意<ChannelList /> コンポーネント.これは、我々のアプリによってホストされるすべてのチャンネルでサイドペインを処理する別のストリームビルトインです.ストリームのAPIは、各チャネルの歴史を維持します.The ChannelList コンポーネントは、新しいチャットが起動されたときにビューを更新するリスナーの負荷を読み込み、メッセージが送信されます.
    The sort オプションは、リストの上部にある最新のメッセージとチャットが表示されます.The Preview 最も最近のメッセージの断片を示します.The onSelectsetChannel ステートメソッドを選択したチャネルを表示します.

    レビュー


    あそこにある.強力な管理ダッシュボードと完全に機能するチャットアプリ.うまくいけば、このチュートリアルはストリームでの作業にいくつかの特別な洞察を提供します.チェックアウトStream Chat Docs and Stream Chat React Docs あなたのプロジェクトのためのより多くのインスピレーションとガイダンスのために.