基于 Laravel + Swoole + Vue 搭建实时在线聊天室(九):实现客服机器人聊天功能

前面我们已经完成了用户认证和 Websocket 服务器的基础组件,接下来,我们正式开始构建聊天室的核心功能,首先,我们来实现机器人聊天功能,机器人聊天后端调用的是第三方机器人接口,所以并不是基于 Websocket 服务器而是基于 HTTP 协议进行通信。

开始之前,我们仍然需要调整下前端的 Muse UI 组件,因为之前的界面是基于 Muse UI 2.0 版本构建的,所以目前组件显示上有些问题。

聊天室相关 Muse UI 组件调整

入口页面

首先是聊天室入口页面 resources/js/pages/Loan.vue,在 Muse UI 3.0 中,mu-list 列表组件的实现做了调整,所以我们需要调整这个 Vue 组件的模板代码如下:

<template>
    <div class="hello">
        <div>
            <mu-list>
                <mu-sub-header>最近聊天记录</mu-sub-header>
                <mu-list-item avatar button :ripple="false" @click="chatwindow('1')">
                    <mu-list-item-action>
                        <mu-avatar>
                            <img :src="house1">
                        </mu-avatar>
                    </mu-list-item-action>
                    <mu-list-item-title>聊天室1</mu-list-item-title>
                    <mu-list-item-action>
                        <mu-icon value="chat_bubble"></mu-icon>
                    </mu-list-item-action>
                </mu-list-item>
                <mu-list-item avatar button :ripple="false" @click="chatwindow('2')">
                    <mu-list-item-action>
                        <mu-avatar>
                            <img :src="house2">
                        </mu-avatar>
                    </mu-list-item-action>
                    <mu-list-item-title>聊天室2</mu-list-item-title>
                    <mu-list-item-action>
                        <mu-icon value="chat_bubble"></mu-icon>
                    </mu-list-item-action>
                </mu-list-item>
            </mu-list>
            <mu-divider></mu-divider>
            <mu-list>
                <mu-sub-header>客服</mu-sub-header>
                <mu-list-item avatar button :ripple="false" @click="chatRobot()">
                    <mu-list-item-action>
                        <mu-avatar>
                            <img :src="robot">
                        </mu-avatar>
                    </mu-list-item-action>
                    <mu-list-item-title>客服大白(微信群,作者联系方式,找我)</mu-list-item-title>
                    <mu-list-item-action>
                        <mu-icon value="chat_bubble"></mu-icon>
                    </mu-list-item-action>
                </mu-list-item>
            </mu-list>
        </div>
    </div>
</template>

调整完成后,运行 npm run dev 重新编译前端资源,然后访问聊天室首页 http://webchats.test/#/,可以看到聊天室列表和客服机器人组件都可以显示出来了:

-w991

房间页面

接下来,我们来看聊天室房间页面组件 resources/js/pages/Chat.vueresources/js/pages/Robot.vue,这两个页面模板中都使用了 mu-icon-buttonmu-raised-button 按钮组件,而在 Muse UI 3.0 中,这两个组件合并为了 mu-button,所以我们需要调整这两个页面中的 Muse UI 按钮组件代码。

调整普通聊天室页面 resources/js/pages/Chat.vue 模板的相关按钮组件代码如下:

<div class="title">
    <mu-appbar title="Title">
        <mu-button icon slot="left" @click="goback">
            <mu-icon value="chevron_left"></mu-icon>
        </mu-button>
      <div class="center">
        聊天({{Object.keys(getUsers).length}})
      </div>
        <mu-button icon slot="right" @click="openSimpleDialog">
            <mu-icon value="people"></mu-icon>
        </mu-button>
    </mu-appbar>
</div>

...

<mu-button class="demo-raised-button" primary @click="submess">发送</mu-button>

调整机器人聊天室页面 resources/js/pages/Robot.vue 模板的相关按钮组件代码如下:

<div class="title">
        <mu-appbar title="Title">
            <mu-button icon slot="left" @click="goback">
                <mu-icon value="chevron_left"></mu-icon>
            </mu-button>
            <div class="center">
            </div>
            <mu-button icon slot="right">
                <mu-icon value="expand_more"></mu-icon>
            </mu-button>
        </mu-appbar>
</div>

...

<mu-button class="demo-raised-button" primary @click="sendmessage">发送</mu-button>

再次运行 npm run dev 编译前端资源,从聊天室入口界面分别进入普通聊天室和机器人聊天室界面,可以看到,页面组件都可以正常渲染出来了:

-w985

-w1415

解决了页面组件渲染问题,接下来,我们来实现机器人聊天功能。

机器人聊天功能实现

图灵机器人接口

这里我们选择图灵机器人提供的 API 接口实现客服机器人功能,这个 API 接口是 http://www.tuling123.com/openapi/api,关于该接口的详细接入指南可以参考官方文档介绍:http://www.tuling123.com/help/h_cent_webapi.jhtml,要接入这个 API,需要在图灵机器人网站注册账号,并创建机器人,然后在具体的机器人项目中获取 API KEY,每次请求接口时都要带上这个 KEY,否则请求会失败。

注:默认测试接口调用次数非常有限,你可以选择通过个人认证提高次数限制。

为了方便管理,我们将 API 接口相关配置定义在 config/services.php 中:

'turingapi' => [
    'url' => 'http://www.tuling123.com/openapi/api',
    'key' => env('ROBOT_KEY')
]

API KEY 属于敏感数据,配置到 .envROBOT_KEY 配置项里面。

定义 Laravel 后端 API 接口

客服机器人聊天功能的流程是这样的:

  • 用户在客服聊天室界面发起会话;
  • Laravel 后台收到请求后,组织出图灵机器人 API 接口要求的数据格式并向图灵 API 接口发起请求;
  • Laravel 后台收到图灵 API 接口返回的数据后,组织出前端可以解析的数据格式将应答信息发送给用户。

可以看到,Laravel 后台接口是一个中介的角色,在这个接口中,需要发送 HTTP 请求并处理响应,这里我们引入 Guzzle 库作为 PHP HTTP 客户端组件,引入之前,先通过 Composer 下载它:

composer require guzzlehttp/guzzle

下载完成之后,在 routes/api.php 定义 robot 路由如下(需要用户认证后才能访问):

Route::middleware('auth:api')->group(function () {
    Route::get('/user', function (Request $request) {
        return $request->user();
    });
    Route::get('/robot', function (Request $request) {
        $info = $request->input('info');
        $userid = $request->input('id');
        $key = config('services.robot.key');
        $url = config('services.robot.api');
        $client = new \GuzzleHttp\Client();
        $response = $client->request('POST', $url, [
            'json' => compact("info", "userid", "key")
        ]);
        return response()->json(['data' => $response->getBody()]);
    });
});

业务逻辑很简单,就是接收前端请求参数,并将这些参数加上 API KEY 作为请求数据再次转发给图灵机器人接口,最后将图灵机器人接口返回的信息转发给前端用户。

这样,后端接口就编写好了。

前端请求参数调整

最后我们打开前端机器人聊天界面文件 resources/js/pages/Robot.vue,在这里,我们需要在用户点击发送按钮发送信息时,带上 api_token 请求字段,以便后端可以通过 auth:api 中间件自动完成基于 API 接口的用户认证:

methods: {
    ...
    sendmessage() {
        ...
        const id = this.userid;
        const api_token = this.auth_token;
        const data = {
            info,
            id,
            api_token
        };
        ...
    }
},
computed: {
    ...mapGetters(["getRobotMsg"]),
    ...mapState({
        userid: state => state.userInfo.userid,
        src: state => state.userInfo.src,
        auth_token: state => state.userInfo.token,
    })
},

代码调整完成后,运行 npm run dev 重新编译前端资源,接下来,我们就可以测试机器人聊天功能了。

测试客服机器人聊天

打开客服机器人聊天界面 http://webchats.test/#/robot,发送消息如下:

-w1009

可以看到,客服大白可以很智能的应答我们发送的消息,测试 API 的调用次数非常有限,如果你看到 暂不支持此类对话 这种回答,很可能是请求次数已经达到上限,可以选择个人认证的方式将每天调用上限提高到 100 次。

上一篇: 基于 Laravel + Swoole + Vue 搭建实时在线聊天室(八):Websocket 服务端重构与用户认证

下一篇: 基于 Laravel + Swoole + Vue 搭建实时在线聊天室(十):用户登录后获取未读消息数