微信小程序_调用openAi搭建虚拟伙伴聊天
- 背景
- 效果
- 关于账号注册
- 接口实现
- 8行python搞定
- 小程序实现
- 页面结构
- 数据逻辑
- 结速
背景
从2022年的年底,网上都是chagpt的传说,个人理解这个chatgpt是模型优化训练,我们在用chatgpt的时候就在优化这个模型,这个是付费的,换言之,我们都是chagpt的韭菜,OpenAI 是一个研究组织,chagpt是他们的一个产品工具。
带着好奇心做了个小程序的聊天页面。
效果
像个机器人聊天
关于账号注册
由于国内电话不支持绑定openAi的邮箱,需要虚拟号码激活具体步骤网上都有教程
接口实现
8行python搞定
install openai,获取apiKey,调用即可向openai发送请求
def getOpenAiText(request):
if request.method == 'GET':
text = request.GET.get('text', default='')
responseText = openai.Completion.create(
model="text-davinci-003",
prompt=text,
max_tokens=100,
temperature=0
)
return JsonResponse({"data": responseText, "code": 200,"msg":'success'})
return JsonResponse({"data": {}, "code": 0,"msg":'not allowed'})
小程序实现
设计思路:灵感来源微信对话框模式一对一
只需要设计数据结构为
[{
question:‘’,
answer:‘’,
isEdit:false
}]
可以显示问答的状态
在添加一个currentIndex标识编辑的状态,遍历数字显示,加上时间绑定即可实现,
缓存采用storage。
页面结构
<view class="container-future">
<view class="form-container-api">
<view>
<button style="width: 100%;" type="primary" formType="submit">openai调用</button>
</view>
<view class="chat-container">
<view wx:for="{{ chatObjConfig.option }}" wx:for-index="index" wx:for-item="item" wx:key="index">
<view class="form-request">
<view wx:if="{{item.isEdit}}">问:$ <input bindinput="bindKeyInput" placeholder="输入关键词" data-column-index="{{index}}" disabled="{{isLoading}}" /></view>
<view wx:else class='questioned'>
<view>
问:$ {{item.question}}
</view>
</view>
</view>
<view class="form-response">
<view class='questioned'>openai回答:$ {{item.answer}}</view>
</view>
</view>
</view>
<view class="form-submit">
<button style="width: 100%;" type="primary" bindtap="search" loading="{{isLoading}}" disabled="{{isLoading}}">发送</button>
</view>
</view>
<view class="loading" wx:if="{{isLoading}}">
<view class="loader-child" />
<view class="loader-child" />
<view class="loader-child" />
</view>
</view>
数据逻辑
// pages/future/future.js
const app = getApp();
const baseUrl = app.remoteConfig.baseUrl;
Component({
/**
* 继承父级样式
*/
options: {
addGlobalClass: true,
},
/**
*组件的初始数据
*/
data: {
searchOpenAiText:'',
responseText:'',
// questions,answer,index
chatObjConfig:{
option:[{
question:'',
answer:'',
isEdit:true
}],
currentIndex:0
}
},
lifetimes: {
// 生命周期函数,可以为函数,或一个在 methods 段中定义的方法名
attached: function () {
if(wx.getStorageSync('openAiOptions')){
this.setData(
{
chatObjConfig:wx.getStorageSync('openAiOptions')
}
)
}
},
moved: function () { },
detached: function () {
wx.setStorageSync('openAiOptions', this.data.chatObjConfig)
},
},
methods: {
bindKeyInput(e) {
const {columnIndex}=e.currentTarget.dataset
console.log('this.data.chatObjConfig',this.data.chatObjConfig)
const option=this.data.chatObjConfig.option
option.some((item,index)=>{
if(columnIndex===index){
item.question=e.detail.value
item.isEdit=true
return true
}
return false
})
this.setData({
searchOpenAiText:e.detail.value,
chatObjConfig:{
option:option,
currentIndex:columnIndex
}
})
},
search(e){
console.log(this.data.searchOpenAiText)
if(!this.data.searchOpenAiText){
wx.showModal({
cancelColor: 'cancelColor',
title:'请输入!'
})
}
wx.showLoading({
title: '加载中',
})
this.setData({
isLoading: true
})
console.log(e)
const path = '/common-api/searchOpenAiText/'
const headers = { 'Content-Type': 'application/json;charset=UTF-8' }
const params={
"text":this.data.searchOpenAiText
}
const thisBack=this
return new Promise((resolve, reject) => {
wx.request({
url: baseUrl + path,
headers: headers,
data:params,
method: 'GET',
success: (res) => {
console.log(res,'res')
const data=res.data.data
const option=thisBack.data.chatObjConfig.option
const currentIndex=thisBack.data.chatObjConfig.currentIndex
const choices=data.choices
console.log('choices',choices)
option.some((item,index)=>{
if(currentIndex===index){
item.answer=choices?choices.map(choicesItem=>{return choicesItem.text}).join('\n'):'。。。未知'
item.isEdit=false
return true
}
return false
})
const chatObjConfig={
option:option,
currentIndex:currentIndex+1
}
option.push({
question:'',
answer:'',
isEdit:true
})
thisBack.setData(
{
isLoading: false,
chatObjConfig:chatObjConfig
}
)
setTimeout(function () {
wx.hideLoading()
}, 2000)
resolve(res)
},
fail: error => {
thisBack.setData({
isLoading: false
})
setTimeout(function () {
wx.hideLoading()
}, 2000)
reject(error)
}
});
})
}
}
})
结速
最后我的小程序:yma16
欢迎大家访问!