vue3 + 微信实现简单的机器人对话
效果图
前置知识
首先开发一个机器人对话我们需要接入微信的智能对话
登陆后可以看到首页
提供了一些基本功能如:
- 简单的对话
- 一些内置的的技能都可以都选上
- 配置欢迎语
- 转人工等等
接入智能对话
- 调用signature接口,获取signature
https://chatbot.weixin.qq.com/openapi/sign/{TOKEN}
signature接口返回体如下:
{
signature: 'xxxxxxxxx'
expiresIn: 7200
}
如何获取token
- TOKEN:发布管理>应用绑定>开发API(按步骤就能拿到token)
2.智能对话接口
https://chatbot.weixin.qq.com/openapi/aibot/{TOKEN}
- POST请求
- 参数说明
- signature:必填,调用signature接口获取到的 signature 返回值
- query:必填,用户发送的消息
- env:非必填,默认是online, debug是测试环境,online是线上环境
- 剩余的参数不做过多说明
- 参数说明
至此只能对话的流程完毕。
vue3 实现对话界面 + 逐字出现的效果实现
<template>
<cu-custom bg-color="bg-white text-black solid-bottom" is-back bg-image="">
<template #backText>返回</template>
</cu-custom>
<div class="chat-box">
<template v-for="(item, index) in talkList.data" :key="index">
<div v-if="item.type == 1" class="is-robot mb-2">
<div class="img"></div>
<div class="content">
<div ref="itemRefs"></div>
</div>
</div>
<div v-if="item.type == 0" class="is-question">
<div class="content">
<div ref="itemRefs"></div>
</div>
<div class="img"></div>
</div>
</template>
<div class="question-panel">
<input v-model="question" />
<button class="send" @click="talk">发送</button>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref, nextTick } from "vue";
import { getToken, wxTalk } from "@/api/index";
import Typed from "typed.js";
const signature = ref("");
const question = ref("");
const talkList: any = ref({ data: [] });
const itemRefs = ref([]);
const init = async () => {
let data: any = await getToken();
signature.value = data.data;
};
const showTyped = (index: number, data: string) => {
nextTick(() => {
let item = itemRefs.value[index];
new Typed(item, {
strings: [data],
typeSpeed: 0,
backSpeed: 50,
showCursor: false,
});
});
};
const talk = async () => {
talkList.value.data.push({
type: 0,
content: question.value,
});
showTyped(talkList.value.data.length - 1, question.value);
let data: any = await wxTalk({
signature: signature.value,
query: question.value,
});
if (data.data) {
talkList.value.data.push({
type: 1,
content: data.data[0].content,
});
showTyped(talkList.value.data.length - 1, data.data[0].content);
}
};
onMounted(() => {
init();
});
</script>
<style lang="scss" scoped>
.chat-box {
width: 750rpx;
height: calc(100vh - 45px);
background: white;
padding: 10px;
}
.is-robot {
display: flex;
.img {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background: url("../../static/wx.jpg");
background-size: 100% 100%;
border: solid 1px #333;
}
.content {
margin-left: 10rpx;
padding: 10rpx;
background-color: #ecf3fe;
max-width: 500rpx;
height: min-content;
border-radius: 20rpx;
}
}
.is-question {
display: flex;
justify-content: flex-end;
.img {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
background: url("../../static/sansan.jpg");
background-size: 100% 100%;
border: solid 1px #333;
}
.content {
margin-right: 10rpx;
padding: 10rpx;
background-color: #ffe7ae;
max-width: 500rpx;
border-radius: 20rpx;
height: min-content;
}
}
.mb-2 {
margin-bottom: 20rpx;
}
.question-panel {
position: fixed;
bottom: 10px;
height: 80rpx;
width: 750rpx;
display: flex;
align-content: center;
left: 0;
.color {
line-height: 80rpx;
}
input {
background-color: #f6f6f5;
height: 80rpx;
margin-left: 10rpx;
width: 600rpx;
border-radius: 20rpx;
}
}
.send {
font-size: 14rpx;
line-height: 80rpx;
background-color: aquamarine;
}
</style>
- talkList:通过type区分是机器人回复还是提问
- getToken:获取signature
- itemRefs:数组ref实例
- talk:对话函数
- showTyped:生成Typed实例
逐字展示的效果依赖第三方库Typed.js
Ending
点个赞吧!