ChatGPT制作一个简单的客服机器人

news2025/1/17 23:26:32

包含功能:

MVP(最简可行产品)版本的客服机器人应该聚焦于核心功能,以快速上线和测试用户反馈为目标。以下是一个简化的版本:

  1. 自动问答(FAQ)功能
    • 支持回答常见问题,例如营业时间、联系方式、退换货政策等。
    • 提供预设的常见问题列表,并能自动匹配用户输入的关键词。
  2. 自然语言处理(NLP)基础
    • 具备基本的语义理解能力,能够识别用户的主要意图并提供相关回答。
  3. 人工客服转接
    • 在遇到无法解答的问题时,能提示用户转接到人工客服。
    • 提供简单的转接方式,例如发送一条信息或链接,告知如何联系人工客服。
  4. 订单查询
    • 允许用户通过输入订单号查询订单状态。
    • 提供基本的订单信息反馈,如订单处理中、已发货、已送达等状态。
  5. 用户反馈收集
    • 在对话结束时,简单地询问用户是否满意,收集基本的满意度反馈。

这个MVP版本的客服机器人可以快速上线,并根据用户反馈逐步增加更多功能和改进。它能够解决用户的一些基本需求,同时保持开发和维护的简洁性。

技术架构:

实现这些MVP功能的客服机器人需要一个清晰的技术架构,确保其高效、稳定地运行。以下是推荐的技术架构:

1. 前端接口

  • 用户界面(UI):在网站或应用中嵌入聊天窗口,可以使用JavaScript库如React或Vue.js来实现。
  • 消息传递:通过WebSocket或REST API与后端服务器进行通信,确保实时消息传递。

2. 后端服务器

  • Web框架:选择Node.js(Express)或Python(Django/Flask)作为主要框架来处理HTTP请求和WebSocket连接。
  • API接口:提供REST API来处理前端发送的请求,如查询订单状态、获取常见问题回答等。

3. 自然语言处理(NLP)

  • NLP引擎:可以使用现成的NLP服务,如Google Dialogflow、Microsoft Azure Bot Service、IBM Watson Assistant,或开源库如Rasa。
  • 意图识别:利用NLP引擎处理用户输入,识别用户意图并生成相应的回答。

4. 数据库

  • 知识库管理:使用一个关系型数据库(如PostgreSQL或MySQL)来存储常见问题和答案。
  • 订单信息:存储和查询订单信息,可能与现有的订单管理系统集成。

5. 人工客服转接

  • 消息队列:使用RabbitMQ或Kafka等消息队列系统来管理和转发用户请求给人工客服。
  • 通知系统:通过Email、短信或内部通知系统告知客服有用户需要帮助。

6. 用户反馈收集

  • 数据库:同样使用关系型数据库来存储用户反馈数据。
  • 简单的反馈接口:在对话结束时,弹出一个简单的评分系统(如星级评分)。

7. 安全和隐私

  • 认证和授权:使用JWT(JSON Web Token)或OAuth进行用户身份认证和授权,确保数据安全。
  • 数据加密:在数据传输过程中使用HTTPS,在存储过程中使用数据库的加密机制。

实现步骤

  1. 前端开发:创建聊天窗口UI,集成WebSocket或REST API进行消息传递。
  2. 后端开发:搭建Web框架,创建API接口,处理用户请求。
  3. NLP集成:选择并集成NLP引擎,处理用户的自然语言输入。
  4. 数据库设置:设计数据库架构,存储常见问题、订单信息和用户反馈。
  5. 人工客服转接:实现消息队列和通知系统,确保用户能顺利转接至人工客服。
  6. 安全措施:实施认证、授权和数据加密,确保用户数据安全。

通过以上架构和步骤,可以有效地实现一个功能完备的MVP客服机器人。

优先级:

  1. 前端开发:搭建基本聊天界面和消息传递。
  2. 后端基础架构:建立服务器和API接口。
  3. NLP集成:实现基本的自然语言处理能力。
  4. 数据库设计:存储常见问题和订单信息。
  5. 人工客服转接:实现消息转发和通知系统。
  6. 用户反馈收集:实现简单的反馈机制。
  7. 安全和隐私保护:确保用户数据的安全性。

windows平台开始前端开发:

1. 设置 Vue 项目

npm install -g @vue/cli

2. 然后创建一个新的 Vue 项目

vue create chat-bot

报错vue:无法加载,因为在此系统上禁止运行脚本

分析原因,权限不足
1. 以管理员身份运行powerShell
2.输入命令: set-ExecutionPolicy RemoteSigned
3. 输入Y
问题解决

继续第二步

在这里插入图片描述

3.创建成功,在vscode中打开项目

3.1. 创建聊天组件

src 目录下创建一个新的组件文件 ChatBot.vue,并添加以下代码:

<template>
  <div class="chat-container">
    <div class="messages">
      <div v-for="(message, index) in messages" :key="index" class="message">
        <div :class="message.sender">{{ message.text }}</div>
      </div>
    </div>
    <div class="input-container">
      <input
        v-model="userInput"
        @keyup.enter="sendMessage"
        type="text"
        placeholder="Type a message..."
      />
      <button @click="sendMessage">Send</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userInput: '',
      messages: [
        { text: 'Hello! How can I help you today?', sender: 'bot' },
      ],
    };
  },
  methods: {
    sendMessage() {
      if (this.userInput.trim() !== '') {
        this.messages.push({ text: this.userInput, sender: 'user' });
        this.userInput = '';
        
        // Simulate bot response
        setTimeout(() => {
          this.messages.push({ text: 'I am still learning. Please ask something else!', sender: 'bot' });
        }, 1000);
      }
    },
  },
};
</script>

<style scoped>
.chat-container {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  border: 1px solid #ccc;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  height: 400px;
}

.messages {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
  border-bottom: 1px solid #ccc;
}

.message {
  margin: 5px 0;
}

.user {
  text-align: right;
  color: blue;
}

.bot {
  text-align: left;
  color: green;
}

.input-container {
  display: flex;
  border-top: 1px solid #ccc;
}

input {
  flex: 1;
  border: none;
  padding: 10px;
  font-size: 16px;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
}

button {
  padding: 10px;
  font-size: 16px;
  border: none;
  background-color: #007bff;
  color: white;
  cursor: pointer;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}

button:hover {
  background-color: #0056b3;
}
</style>

3.2 注册组件并启动应用

src/App.vue 中注册并使用 ChatBot 组件:

<template>
  <div id="app">
    <ChatBot />
  </div>
</template>

<script>
import ChatBot from './components/ChatBot.vue';

export default {
  name: 'App',
  components: {
    ChatBot,
  },
};
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

3.3 运行应用

确保你在项目目录下,然后运行以下命令启动应用:

npm run serve

在这里插入图片描述

在这里插入图片描述

3.4访问http://localhost:8080/

在这里插入图片描述

支持简单输出和回复

在这里插入图片描述

后端flask实现

在D盘创建flaskproject

1.初始化项目

mkdir flask-chat-bot
cd flask-chat-bot
python -m venv venv
venv\Scripts\activate

2.安装Flask

安装Flask和Flask-CORS:

pip install Flask Flask-CORS

3.创建Flask应用

用PyCharm里面,在项目根目录下创建一个 app.py 文件,并添加以下代码:

# app.py
from flask import Flask, request, jsonify
from flask_cors import CORS
import random

app = Flask(__name__)
CORS(app)

# 模拟的机器人回复
bot_responses = [
    "I'm still learning. Please ask something else!",
    "Can you please elaborate?",
    "I'm here to help you. What do you need?",
]

def get_bot_response():
    return random.choice(bot_responses)

@app.route('/api/chat/message', methods=['POST'])
def chat():
    user_message = request.json.get('message')
    if not user_message:
        return jsonify({'error': 'Message is required'}), 400

    # 模拟处理用户消息并生成回复
    bot_message = get_bot_response()

    return jsonify({
        'userMessage': user_message,
        'botMessage': bot_message,
    })

if __name__ == '__main__':
    app.run(debug=True)

报错ModuleNotFoundError: No module named ‘flask_cors’,flask_cors下载失败

分析问题:python312版本和pycharm的310版本间出现冲突
解决问题:
删除310版本,更改pycharm的本地配置解释器为312版本
C:\Users\Administrator\AppData\Local\Programs\Python\Python312
问题解决。

在这里插入图片描述

4.启动Flask服务器

在终端中运行以下命令启动Flask服务器:

python app.py

Flask服务器将在 http://localhost:5000 上运行。

在这里插入图片描述

REST API消息传递功能

基于Windows系统的Flask后端和Vue.js前端的REST API消息传递功能

1.修改ChatBot.vue文件

<template>
  <div class="chat-container">
    <div class="messages">
      <div v-for="(message, index) in messages" :key="index" class="message">
        <div :class="message.sender">{{ message.text }}</div>
      </div>
    </div>
    <div class="input-container">
      <input
        v-model="userInput"
        @keyup.enter="sendMessage"
        type="text"
        placeholder="Type a message..."
      />
      <button @click="sendMessage">Send</button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userInput: '',
      messages: [
        { text: 'Hello! How can I help you today?', sender: 'bot' },
      ],
    };
  },
  methods: {
    async sendMessage() {
      if (this.userInput.trim() !== '') {
        this.messages.push({ text: this.userInput, sender: 'user' });

        // 保存用户输入
        const userMessage = this.userInput;
        this.userInput = '';

        try {
          // 发送请求到后端API
          const response = await fetch('http://localhost:5000/api/chat/message', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ message: userMessage }),
          });
          const data = await response.json();

          // 显示机器人的回复
          this.messages.push({ text: data.botMessage, sender: 'bot' });
        } catch (error) {
          console.error('Error:', error);
        }
      }
    },
  },
};
</script>

<style scoped>
.chat-container {
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
  border: 1px solid #ccc;
  border-radius: 5px;
  display: flex;
  flex-direction: column;
  height: 400px;
}

.messages {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
  border-bottom: 1px solid #ccc;
}

.message {
  margin: 5px 0;
}

.user {
  text-align: right;
  color: blue;
}

.bot {
  text-align: left;
  color: green;
}

.input-container {
  display: flex;
  border-top: 1px solid #ccc;
}

input {
  flex: 1;
  border: none;
  padding: 10px;
  font-size: 16px;
  border-top-left-radius: 5px;
  border-bottom-left-radius: 5px;
}

button {
  padding: 10px;
  font-size: 16px;
  border: none;
  background-color: #007bff;
  color: white;
  cursor: pointer;
  border-top-right-radius: 5px;
  border-bottom-right-radius: 5px;
}

button:hover {
  background-color: #0056b3;
}
</style>

效果

在这里插入图片描述

接入openapi替代NLP技术实现

技术架构更改

1. 前端
  • 技术栈:Vue.js

  • 功能

    • 用户界面:提供一个简单的聊天界面。
    • 输入处理:用户输入消息并发送。
    • 消息显示:显示用户消息和机器人回复。
2. 后端
  • 技术栈:Flask(Python)

  • 功能

    • 接收前端发送的消息。
    • 调用OpenAI的API处理用户消息。
    • 返回OpenAI的回复给前端。
3. 第三方服务
  • OpenAI API

    • 用于生成聊天机器人的回复。

具体流程

  1. 用户输入消息
    • 用户在Vue.js前端输入消息并点击发送。
  2. 前端发送请求
    • 前端通过REST API将用户消息发送到Flask服务器。
  3. 后端处理请求
    • Flask服务器接收到请求后,提取用户消息。
    • 调用OpenAI的API,将用户消息发送给OpenAI。
  4. OpenAI生成回复
    • OpenAI根据用户消息生成合适的回复。
  5. 后端返回回复
    • Flask服务器接收到OpenAI的回复后,将其发送回前端。
  6. 前端显示回复
    • Vue.js前端接收到服务器返回的回复,并在聊天界面中显示
|-------------|        HTTP         |--------------|       HTTP       |---------------|
|   Frontend  | <-----------------> |   Backend    | <--------------> | OpenAI API    |
|   Vue.js    |     REST API        |   Flask      |    API Request   |               |
|-------------|                     |--------------|                  |---------------|
    |   |                               |   |
   User input                        Process request
    |   |                               |   |
Send message ---> Receive message ---> Call OpenAI
    |   |                               |   |
Display reply <--- Return reply <--- Get reply

后端代码优化

# app.py
from flask_cors import CORS
from flask import Flask, request, jsonify
from openai import OpenAI
from dotenv import load_dotenv, find_dotenv

app = Flask(__name__)
CORS(app)


_ = load_dotenv(find_dotenv())

client = OpenAI()

@app.route('/api/chat/message', methods=['POST'])
def chat():
    user_message = request.json.get('message')
    if not user_message:
        return jsonify({'error': 'Message is required'}), 400

    messages = [
        {"role": "system", "content": "你是一个客服机器人"},
        {"role": "user", "content": user_message}
    ]
    print(messages)

    try:
        # 调用OpenAI API获取回复
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=messages
        )
        bot_message = response.choices[0].message.content
        print(bot_message)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

    return jsonify({
        'userMessage': user_message,
        'botMessage': bot_message,
    })

if __name__ == '__main__':
    app.run(debug=True)

前端代码优化

<template>
    <div class="chat-container">
      <div class="messages">
        <div v-for="(message, index) in messages" :key="index" class="message">
          <div :class="message.sender">{{ message.text }}</div>
        </div>
      </div>
      <div class="input-container">
        <input
          v-model="userInput"
          @keyup.enter="sendMessage"
          type="text"
          placeholder="Type a message..."
        />
        <button @click="sendMessage">Send</button>
      </div>
    </div>
  </template>
  
  <script>
  export default {
    data() {
      return {
        userInput: '',
        messages: [
          { text: 'Hello! How can I help you today?', sender: 'bot' },
        ],
      };
    },
    methods: {
      async sendMessage() {
      if (this.userInput.trim() !== '') {
        this.messages.push({ text: this.userInput, sender: 'user' });

        // 保存用户输入
        const userMessage = this.userInput;
        this.userInput = '';

        try {
          // 发送请求到后端API
          const response = await fetch('http://localhost:5000/api/chat/message', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({ message: userMessage }),
          });
          const data = await response.json();

          // 显示机器人的回复
          this.messages.push({ text: data.botMessage, sender: 'bot' });
        } catch (error) {
          console.error('Error:', error);
        }
      }
    },
  },
  };
  </script>
  
  <style scoped>
  .chat-container {
    width: 100%;
    max-width: 600px;
    margin: 0 auto;
    border: 1px solid #ccc;
    border-radius: 5px;
    display: flex;
    flex-direction: column;
    height: 400px;
  }
  
  .messages {
    flex: 1;
    padding: 10px;
    overflow-y: auto;
    border-bottom: 1px solid #ccc;
  }
  
  .message {
    margin: 5px 0;
  }
  
  .user {
    text-align: right;
    color: blue;
  }
  
  .bot {
    text-align: left;
    color: green;
  }
  
  .input-container {
    display: flex;
    border-top: 1px solid #ccc;
  }
  
  input {
    flex: 1;
    border: none;
    padding: 10px;
    font-size: 16px;
    border-top-left-radius: 5px;
    border-bottom-left-radius: 5px;
  }
  
  button {
    padding: 10px;
    font-size: 16px;
    border: none;
    background-color: #007bff;
    color: white;
    cursor: pointer;
    border-top-right-radius: 5px;
    border-bottom-right-radius: 5px;
  }
  
  button:hover {
    background-color: #0056b3;
  }
  </style>
  

更改后的效果如下

在这里插入图片描述

接入数据库

使用mysql数据库接入,通过OpenAI API查询本地数据库以获取真实的订单信息

创建数据库并插入数据

采用DBeaver创建zh数据库并建立order表,插入数据

CREATE DATABASE order_db;

USE order_db;

CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_number VARCHAR(50) NOT NULL,
    customer_name VARCHAR(100),
    product VARCHAR(100),
    quantity INT,
    status VARCHAR(50)
);

-- 插入一些示例数据
INSERT INTO orders (order_number, customer_name, product, quantity, status)
VALUES
('ORD001', 'Alice', 'Laptop', 1, 'Shipped'),
('ORD002', 'Bob', 'Smartphone', 2, 'Processing'),
('ORD003', 'Charlie', 'Tablet', 1, 'Delivered');

在这里插入图片描述

数据库连接

添加app.py连接数据库

# 数据库配置
db_config = {
    'user': 'root',
    'password': 'your_mysql_password',  # 在此处替换为你的MySQL密码
    'host': '127.0.0.1',
    'database': 'order_db',
    'raise_on_warnings': True
}

查询订单信息

# 查询订单信息
def get_order_info(order_number):
    try:
        cnx = mysql.connector.connect(**db_config)
        cursor = cnx.cursor(dictionary=True)

        query = "SELECT * FROM orders WHERE order_number = %s"
        cursor.execute(query, (order_number,))

        result = cursor.fetchone()
        cursor.close()
        cnx.close()
        
        return result
    except mysql.connector.Error as err:
        return {'error': str(err)}

chatgpt 访问数据库

添加chatgpt访问数据库

def get_completion(messages):
    # 调用OpenAI API获取回复
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature=0,
        tools=[{
            "type": "function",
            "function": {
                "name": "get_order_id",
                "description": "Get the current order id",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "order_id": {
                            "type": "string",
                            "description": "订单号格式为ORD开头",
                        }
                    },
                    "required": ["order_id"],
                },
            }
        }],
    )
    return response.choices[0].message


@app.route('/api/chat/message', methods=['POST'])
def chat():
    user_message = request.json.get('message')
    if not user_message:
        return jsonify({'error': 'Message is required'}), 400

    messages = [
        {"role": "system", "content": "你是一个客服机器人"},
        {"role": "user", "content": user_message}
    ]
    print(messages)

    try:
        # 调用OpenAI API获取回复
        response = get_completion(messages)
        bot_content = response.content
        print(f'bot_content:', bot_content)
        if bot_content:
            return jsonify({
                'userMessage': user_message,
                'botMessage': bot_content,
            })
        bot_message = response
        print(f'bot_message:', bot_message)
        messages.append(bot_message)
        if (response.tool_calls is not None):
            tool_call = response.tool_calls[0]
            print(f'tool_call:', tool_call)
            if (tool_call.function.name == 'get_order_id'):
                print(f'get_order_id:')
                args = json.loads(tool_call.function.arguments)
                order_id = get_order_info(**args)
                print(f'order_id:', order_id)

                messages.append(
                    {
                        "role": "tool",
                        "content": "Order ID: " + str(order_id),
                        "tool_call_id": tool_call.id
                    }
                )

                print(f'messages:', messages)

                response = get_completion(messages)
                print(f'response:', response)
                return jsonify({
                    'userMessage': user_message,
                    'botMessage': response.content,
                })

    except Exception as e:
        return jsonify({'error': str(e)}), 500

    return jsonify({
        'userMessage': user_message,
        'botMessage': bot_message,
    })

chatgpt api调用官网

重新启动服务器

效果如下,可以看到成功查询到本地数据库订单号为ORD001的订单状态信息,并且成功返回客户端界面:

在这里插入图片描述

MySQL存储常见问题和答案

1.数据库创建

数据库中创建一个名为 faqs 的表,存储常见问题和答案

CREATE TABLE faqs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    question TEXT NOT NULL,
    answer TEXT NOT NULL
);

插入数据

INSERT INTO faqs (question, answer) VALUES
('如何重置密码?', '要重置密码,请转到登录页面并点击“忘记密码”链接。按照说明重置您的密码。'),
('退货政策是什么?', '我们的退货政策允许您在购买后30天内退货。请确保产品处于原始状态。'),
('如何跟踪我的订单?', '要跟踪订单,请登录您的账户并转到“订单”部分。点击您想要跟踪的订单以查看最新状态。'),
('我可以更改收货地址吗?', '是的,您可以在订单发货前更改收货地址。请联系客户服务以获取帮助。'),
('你们接受哪些付款方式?', '我们接受多种付款方式,包括信用卡、借记卡、PayPal和银行转账。'),
('如何联系客户支持?', '您可以通过电子邮件support@example.com联系我们的客户支持,或拨打1-800-123-4567。'),
('你们的工作时间是什么时候?', '我们的客户支持时间为周一至周五,上午9点到下午5点。'),
('如何取消我的订单?', '要取消订单,请登录您的账户,转到“订单”部分,然后选择您要取消的订单。如果订单尚未发货,您将看到“取消订单”选项。'),
('你们提供国际运输吗?', '是的,我们提供大多数国家的国际运输。运费和交货时间因目的地而异。'),
('如何使用折扣码?', '要使用折扣码,请在结账时在“折扣码”字段中输入代码并点击“应用”。折扣将应用到您的订单总额。');

数据库显示及如下:

在这里插入图片描述

2.整合到Flask应用

接下来,我们需要调整Flask应用以支持FAQ查询。我们将实现一个新的API端点,用于从数据库中检索常见问题和答案。

# 查询FAQ
def get_faq(question):
    try:
        cnx = mysql.connector.connect(**db_config)
        cursor = cnx.cursor(dictionary=True)

        query = "SELECT answer FROM faqs WHERE question LIKE %s"
        cursor.execute(query, ("%"+question+"%",))

        result = cursor.fetchone()
        cursor.close()
        cnx.close()
        
        return result
    except mysql.connector.Error as err:
        return {'error': str(err)}

添加chatgpt功能部分代码

            {
                "type": "function",
                "function": {
                    "name": "get_faq",
                    "description": "Get the current question id",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "question": {
                                "type": "string",
                                "description": "question should be a question in table",
                            }
                        },
                        "required": ["question"],

                    },
                }

增加返回值判断

 elif (tool_call.function.name == 'get_faq'):
                print(f'get_faq:')
                args = json.loads(tool_call.function.arguments)
                answer = get_faq(**args)
                print(f'question_id:', answer)

                messages.append(
                    {
                        "role": "tool",
                        "content": "answer: " + str(answer),
                        "tool_call_id": tool_call.id
                    }
                )

                print(f'messages:', messages)

                response = get_completion(messages)
                print(f'response:', response)
                return jsonify({
                    'userMessage': user_message,
                    'botMessage': response.content,
                })

效果如下:

在这里插入图片描述

ChatGPT的聊天过程

https://chatgpt.com/share/cd990a21-86d5-4a6c-ac0b-b3a775738d5a

人工客服转接

为了使用RabbitMQ消息队列系统来管理和转发用户请求给人工客服,我们需要设置RabbitMQ服务器,并且在Flask后端实现发送消息到RabbitMQ的功能。在接收端,可以实现一个消费者程序,实时监听队列并将请求分配给人工客服。

1. 安装RabbitMQ

首先,你需要在你的系统上安装RabbitMQ。可以参考RabbitMQ官方文档进行安装。

由于本机的docker和vm虚拟器冲突无法使用docker,按照传统方式安装rabbitMQ

以下是具体的命令和下载链接:

下载Erlang:

访问Erlang Solutions的官方网站下载最新版本的Erlang:https://www.erlang.org/downloads

安装Erlang:

双击下载的exe文件,按提示进行安装。

设置环境变量,将Erlang的安装目录和bin目录添加到系统的PATH变量中。

下载RabbitMQ:

访问RabbitMQ官方网站下载最新版本的RabbitMQ:https://www.rabbitmq.com/download.html

安装RabbitMQ:

双击下载的exe文件,按提示进行安装。

可以使用RabbitMQ Plugin来管理和扩展RabbitMQ的功能,通过命令行运行以下命令来启用管理界面:

rabbitmq-plugins enable rabbitmq_management
访问RabbitMQ管理界面:

打开浏览器,访问 http://localhost:15672 ,使用默认用户guest和密码guest登录RabbitMQ管理界面。

注意:如果在安装过程中遇到问题,请确保你的Windows系统支持RabbitMQ,并查看官方文档以获取更多信息和解决方案。

2. 配置RabbitMQ

安装完RabbitMQ后,启动RabbitMQ服务:

sudo service rabbitmq-server start

3. 安装Pika库

Pika是Python的RabbitMQ客户端库。可以通过pip安装:

pip install pika

4. 修改Flask后端以发送消息到RabbitMQ

我们将在Flask后端添加一个新的路由,将用户请求发送到RabbitMQ队列中。

# 发送消息到RabbitMQ
def send_to_rabbitmq(message):
    try:
        connection = pika.BlockingConnection(pika.ConnectionParameters(host=rabbitmq_host))
        channel = connection.channel()

        channel.queue_declare(queue=queue_name, durable=True)
        channel.basic_publish(
            exchange='',
            routing_key=queue_name,
            body=message,
            properties=pika.BasicProperties(
                delivery_mode=2,  # make message persistent
            ))
        connection.close()
    except Exception as e:
        print(f"Failed to send message to RabbitMQ: {e}")

        
        # 将用户消息发送到RabbitMQ队列
    send_to_rabbitmq(user_message)

5. 创建消费者以处理RabbitMQ消息

接下来,我们创建一个消费者程序,它会监听RabbitMQ队列,并将用户请求分配给人工客服。

# consumer.py
import pika

rabbitmq_host = 'localhost'
queue_name = 'customer_requests'

def callback(ch, method, properties, body):
    print(f"Received {body}")
    # 在此处处理消息,将其分配给人工客服
    # 比如通过邮件、通知系统等方式
    ch.basic_ack(delivery_tag=method.delivery_tag)

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host=rabbitmq_host))
    channel = connection.channel()

    channel.queue_declare(queue=queue_name, durable=True)
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(queue=queue_name, on_message_callback=callback)

    print('Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

if __name__ == '__main__':
    main()

6. 运行系统

  1. 启动RabbitMQ服务器

    sudo service rabbitmq-server start
    
    
  2. 启动Flask应用

    python app.py
    
    

    3., 启动RabbitMQ消费者

    python consumer.py
    
    

    4; 测试应用

    在浏览器中访问 http://localhost:8080,输入消息发送到后端,确认消息被成功发送到RabbitMQ,并在消费者端被接收和处理。

    通过这些步骤,你就可以实现使用RabbitMQ消息队列系统管理和转发用户请求给人工客服的功能。

效果如下:

通过Email告知客服有用户需要帮助

为了通过Email告知客服有用户需要帮助,我们需要在消费者程序中添加发送电子邮件的功能。我们可以使用Python的smtplib库来实现发送邮件。下面是更新后的消费者代码,添加了通过电子邮件通知客服的功能。

更新消费者程序以发送Email

首先,确保你有一个SMTP服务器和有效的电子邮件账户来发送通知邮件。下面是一个使用Gmail SMTP服务器的示例。

# consumer.py
import pika
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

rabbitmq_host = 'localhost'
queue_name = 'customer_requests'
smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_user = 'your_email@gmail.com'  # 在此处替换为你的电子邮件
smtp_password = 'your_email_password'  # 在此处替换为你的电子邮件密码
customer_support_email = 'support@example.com'  # 在此处替换为客服的电子邮件

def send_email(user_message):
    subject = "New Customer Request"
    body = f"You have a new customer request:\n\n{user_message}"

    msg = MIMEMultipart()
    msg['From'] = smtp_user
    msg['To'] = customer_support_email
    msg['Subject'] = subject

    msg.attach(MIMEText(body, 'plain'))

    try:
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.starttls()
        server.login(smtp_user, smtp_password)
        text = msg.as_string()
        server.sendmail(smtp_user, customer_support_email, text)
        server.quit()
        print(f"Email sent to {customer_support_email}")
    except Exception as e:
        print(f"Failed to send email: {e}")

def callback(ch, method, properties, body):
    user_message = body.decode()
    print(f"Received {user_message}")

    # 发送邮件通知客服
    send_email(user_message)

    ch.basic_ack(delivery_tag=method.delivery_tag)

def main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(host=rabbitmq_host))
    channel = connection.channel()

    channel.queue_declare(queue=queue_name, durable=True)
    channel.basic_qos(prefetch_count=1)
    channel.basic_consume(queue=queue_name, on_message_callback=callback)

    print('Waiting for messages. To exit press CTRL+C')
    channel.start_consuming()

if __name__ == '__main__':
    main()

配置和运行

  1. 安装必要的Python库

确保安装了pika和smtplib库,如果没有安装,可以使用pip安装:

pip install pika

smtplib是Python标准库的一部分,因此不需要额外安装。

  1. 配置SMTP服务器信息

在代码中,替换以下变量为你自己的SMTP服务器信息和邮件账户信息:

smtp_server = 'smtp.gmail.com'
smtp_port = 587
smtp_user = 'your_email@gmail.com'
smtp_password = 'your_email_password'
customer_support_email = 'support@example.com'

  1. 运行消费者程序
python consumer.py

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1790614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一键分割视频并生成M3U8格式:高效管理视频内容,畅享流畅播放新体验

视频内容已成为我们日常生活和工作中的重要组成部分。无论是个人分享生活点滴&#xff0c;还是企业宣传产品与服务&#xff0c;视频都以其直观、生动的形式&#xff0c;吸引着我们的眼球。然而&#xff0c;随着视频内容的不断增多&#xff0c;如何高效、便捷地管理这些视频&…

虚幻引擎5 Gameplay框架(四)

Gameplay重要类及重要功能使用方法&#xff08;三&#xff09; 虚幻的委托机制 虚幻委托之间的区别序列化就是是否可以在蓝图中执行 多播与单播的创建 制作功能&#xff1a;使用多播与单播将血条与血量进行实时更新首先新建一个单播与一个多播委托 实例化这两个委托的标签…

6.5 作业

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数。 #include <iostream>using namespace std; class Stu { privat…

低温测控芯片迎来突破性进展!

为支持大规模超导量子计算机的开发&#xff0c;日本最大的公共研究机构之一国家先进工业科学与技术研究所 (AIST) 的研究人员与横滨国立大学、东北大学&#xff08;日本国立大学之一&#xff09;和NEC公司合作&#xff0c;提出并成功演示了一种可在低温下控制许多量子比特的超导…

CSAPP Lab08——Proxy Lab完成思路

蓝色的思念 突然演变成了阳光的夏天 空气中的温暖不会很遥远 ——被风吹过的夏天 完整代码见&#xff1a;CSAPP/proxylab-handout at main SnowLegend-star/CSAPP (github.com) Q&#xff1a;计算机网络中port的作用是什么&#xff1f; A&#xff1a;在计算机网络中&#xff…

下载安装Grafana 监控mysql和Linux主机

下载地址:https://grafana.com/grafana/download [rootlocalhost ~]# wget https://dl.grafana.com/oss/release/grafana-7.2.0- 1.x86_64.rpm 安装 [rootlocalhost ~]# yum install grafana-7.2.0-1.x86_64.rpm -y启动服务 [rootlocalhost ~]# systemctl enable --now grafa…

AST 在前端开发中的应用与实践:从代码分析到自动化转换

抽象语法树&#xff08;AST&#xff0c;Abstract Syntax Tree&#xff09;在前端开发中有着广泛的应用。它是编译器和工具链的核心组件&#xff0c;使得代码分析、转换、优化等操作成为可能。在前端开发中&#xff0c;AST 主要用于代码编译和转译、代码优化、代码分析、代码格式…

C语言数字全排列生成器

前言 从0开始记录我的学习历程&#xff0c;我会尽我所能&#xff0c;写出最最大白话的文章&#xff0c;希望能够帮到你&#xff0c;谢谢。 提示&#xff1a;文章作者为初学者&#xff0c;有问题请评论指正&#xff0c;感谢。 这个代码的功能是生成并打印出从1到N的所有整数的…

Allegro-开店指南

开店指南 Allegro企业账户注册流程 Allegro注册流程分成两个主要阶段: 第一创建您的账户&#xff0c;第二激活您账户的销售功能。完成两个阶段&#xff0c;才能在Allegro进行销售。 中国企业应该入驻Business account&#xff08;企业账户&#xff09;。 第二阶段&#xff…

nginx中配置ssl证书(宝塔面板)

首先申请一个SSL证书&#xff0c;这里我申请的joyssl的免费证书。提交订单申请后&#xff0c;按照页面提示在域名解析中将CNAME和记录值配置好。 比如我用的阿里云&#xff0c; 这是好后&#xff0c;需要等几分钟&#xff0c;然后域名检验成功。 然后点击joyssl的左侧菜单的“证…

【新书上市】图像画质算法与底层视觉技术

图书主页&#xff1a;https://book.douban.com/subject/36895899/ 购买链接&#xff1a;https://item.jd.com/10105601481762.html 内容介绍 本书主要介绍了图像画质相关的各类底层视觉任务及其相关算法&#xff0c;重点讲解了去噪、超分辨率、去雾、高动态范围、图像合成与图…

conflicting types for 错误问题

操作系统真象还原中&#xff0c;第十一章出现的问题&#xff1a; 怎样编译都会出现一个conflicting types for ’xxx‘的错误 出现这个错误的原因&#xff1a; 头文件声明和定义参数稍有不同 头文件中声明 void Hanlder(const char * buf); 在定义时写作 void Hanlder(char…

双指针法 ( 三数之和 )

题目 &#xff1a;给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复…

嵌入式 Linux LED 驱动开发实验学习

I.MX6U-ALPHA 开发板上的 LED 连接到 I.MX6ULL 的 GPIO1_IO03 这个引脚上&#xff0c;进行这个驱动开发实验之前&#xff0c;需要了解下地址映射。 地址映射 MMU 全称叫做 MemoryManage Unit&#xff0c;也就是内存管理单元。在老版本的 Linux 中要求处理器必须有 MMU&#x…

Amazon云计算AWS(一)

目录 一、基础存储架构Dynamo&#xff08;一&#xff09;Dynamo概况&#xff08;二&#xff09;Dynamo架构的主要技术 二、弹性计算云EC2&#xff08;一&#xff09;EC2的基本架构&#xff08;二&#xff09;EC2的关键技术&#xff08;三&#xff09;EC2的安全及容错机制 提供的…

NXP i.MX8系列平台开发讲解 - 3.14 Linux 之Power Supply子系统(二)

专栏文章目录传送门&#xff1a;返回专栏目录 Hi, 我是你们的老朋友&#xff0c;主要专注于嵌入式软件开发&#xff0c;有兴趣不要忘记点击关注【码思途远】 目录 1. 前言 2. 芯片简介 2. 系统原理设计 2. 设备树相关 本文实操是基于Android11 系统下i.MX8MQ环境下&#x…

DKTCDR:Domain-Oriented Knowledge Transfer for Cross-Domain Recommendation

Domain-Oriented Knowledge Transfer for Cross-Domain Recommendation IEEE(CCF B.SCI 1)-Guoshuai Zhao, Xiaolong Zhang, Hao Tang, Jialie Shen, and Xueming Qian-2024 思路 在CDR中,构建连接两个域的桥梁是实现跨域推荐的基础。然而现在的CDR方法往往在连接两个域时忽…

STM32-- GPIO->EXTI->NVIC中断

一、NVIC简介 什么是 NVIC &#xff1f; NVIC 即嵌套向量中断控制器&#xff0c;全称 Nested vectored interrupt controller 。它 是内核的器件&#xff0c;所以它的更多描述可以看内核有关的资料。M3/M4/M7 内核都是支持 256 个中断&#xff0c;其中包含了 16 个系统中…

调用smc为什么就能直接切换到ATF?

快速链接: . &#x1f449;&#x1f449;&#x1f449;Trustzone/TEE/安全 面试100问-目录 &#x1f448;&#x1f448;&#x1f448; 付费专栏-付费课程 【购买须知】:联系方式-加入交流群 ----联系方式-加入交流群 个人博客笔记导读目录(全部) 背景 插播一个小插曲&#…

图片的dpi数值怎么修改?快速在线改图片dpi的操作技巧

在网上报名或者上传个人证件照片时&#xff0c;经常会对图片dpi数值有所要求&#xff0c;需要按照要求将图修改图片dpi到规定数值才可以正常上传&#xff0c;有很多人都对这个问题的感到非常的困扰&#xff0c;那么有什么方法能够快速在线改图片分辨率的dpi数值呢&#xff1f; …