乐趣区

创建聊天机器人以协助网络操作

创建聊天机器人以协助网络操作

来源 | 愿码 (ChainDesk.CN) 内容编辑
愿码 Slogan | 连接每个程序员的故事
网站 | http://chaindesk.cn

愿码愿景 | 打造全学科 IT 系统免费课程,助力小白用户、初级工程师 0 成本免费系统学习、低成本进阶,帮助 BAT 一线资深工程师成长并利用自身优势创造睡后收入。
官方公众号 | 愿码 | 愿码服务号 | 区块链部落
免费加入愿码全思维工程师社群 | 任一公众号回复“愿码”两个字获取入群二维码

本文阅读时长:11min
在本文中,我们将了解如何利用聊天机器人来协助网络操作。随着我们向智能化运营迈进,另一个需要关注的领域是移动性。有一个脚本可以执行配置,修复甚至故障排除,但它仍然需要存在来监视,启动甚至执行这些程序或脚本。
诺基亚的 MIKA 是操作人员可以用来进行网络故障排除和修复的聊天机器人的一个很好的例子。根据诺基亚的博客,MIKA 根据此单个网络的实际情况响应警报优先级信息,并将当前情况与此网络及其他网络过去事件的整个服务历史进行比较,以确定当前网络的最佳解决方案。
让我们创建一个聊天机器人来协助网络运营。对于这个用例,我们将使用广泛使用的聊天应用程序 Slack。参考 Splunk 的智能数据分析功能,我们会看到一些用户聊天与聊天机器人的交互,以获得对环境的一些了解。
当我们部署了我们的 Web 框架时,我们将利用相同的框架与 Slack 聊天机器人进行交互,而后者又将与 Splunk 进行交互。它还可以直接与网络设备交互,因此我们可以启动一些复杂的聊天,例如在需要时从 Slack 重启路由器。这最终为工程师提供了移动性,他可以从任何地方(甚至是手机)处理任务,而不必绑定到某个位置或办公室。
要创建聊天机器人,以下是基本步骤:
在 Slack 上创建一个工作区(或帐户):

在工作区中创建一个应用程序(在我们的例子中,我们创建了一个名为的应用程序 mybot):

以下是有关应用程序的基本信息(应用程序 ID 和客户端 ID 可以与唯一标识此应用程序的其他信息一起使用):

为此应用程序添加 bot 功能:

添加事件订阅并映射到将要发布消息的外部 API。事件订阅是指某人在聊天中键入对聊天机器人的引用,然后将使用此聊天机器人与聊天中键入的数据调用哪个 API:

在这里,关键的一步是,一旦我们输入接受聊天消息的 URL,就需要从 Slack 验证特定的 URL。验证涉及 API 端点将相同的响应作为从 Slack 发送到该端点的字符串或 JSON 发回。如果我们收到相同的响应,Slack 确认端点是可信的并将其标记为已验证。这是一次性过程,API URL 中的任何更改都将导致重复此步骤。
以下是 Ops API 框架中的 Python 代码,它响应此特定查询:
import falcon
import json
def on_get(self,req,resp):
# Handles GET request
resp.status=falcon.HTTP_200 # Default status
resp.body=json.dumps({“Server is Up!”})
def on_post(self,req,resp):
# Handles POST Request
print(“In post”)
data=req.bounded_stream.read()
try:
# Authenticating end point to Slack
data=json.loads(data)[“challenge”]
# Default status
resp.status=falcon.HTTP_200
# Send challenge string back as response
resp.body=data
except:
# URL already verified
resp.status=falcon.HTTP_200
resp.body=””
这将验证,如果从 Slack 发送质询,它将回复相同的质询值,确认它是 Slack 通道发送聊天数据的正确端点。
将此应用程序(或聊天机器人)安装到任何渠道(这类似于在群聊中添加用户):

响应特定聊天消息的核心 API 框架代码执行以下操作:
· 确认发送给 Slack 的任何帖子都会 200 在三秒内响应。如果没有这样做,Slack 报告说:endpoint not reachable。
· 确保从聊天机器人(不是来自任何真实用户)发送的任何消息再次不作为回复发回。这可以创建一个循环,因为从聊天机器人发送的消息将被视为 Slack 聊天中的新消息,并且它将再次发送到 URL。这最终会使聊天无法使用,从而导致聊天中出现重复的消息。
· 使用将被发送回 Slack 的令牌对响应进行身份验证,以确保来自 Slack 的响应来自经过身份验证的源。
代码如下:
import falcon
import json
import requests
import base64
from splunkquery import run
from splunk_alexa import alexa
from channel import channel_connect,set_data
class Bot_BECJ82A3V():
def on_get(self,req,resp):
# Handles GET request
resp.status=falcon.HTTP_200 # Default status
resp.body=json.dumps({“Server is Up!”})
def on_post(self,req,resp):
# Handles POST Request
print(“In post”)
data=req.bounded_stream.read()
try:
bot_id=json.loads(data)[“event”][“bot_id”]
if bot_id==”BECJ82A3V”:
print(“Ignore message from same bot”)
resp.status=falcon.HTTP_200
resp.body=””
return
except:
print(“Life goes on. . .”)
try:
# Authenticating end point to Slack
data=json.loads(data)[“challenge”]
# Default status
resp.status=falcon.HTTP_200
# Send challenge string back as response
resp.body=data
except:
# URL already verified
resp.status=falcon.HTTP_200
resp.body=””
print(data)
data=json.loads(data)
#Get the channel and data information
channel=data[“event”][“channel”]
text=data[“event”][“text”]
# Authenticate Agent to access Slack endpoint
token=”xoxp-xxxxxx”
# Set parameters
print(type(data))
print(text)
set_data(channel,token,resp)
# Process request and connect to slack channel
channel_connect(text)
return
# falcon.API instance , callable from gunicorn
app= falcon.API()
# instantiate helloWorld class
Bot3V=Bot_BECJ82A3V()
# map URL to helloWorld class
app.add_route(“/slack”,Bot3V)
执行频道交互响应:此代码负责在聊天频道中解释使用 chat-bot 执行的特定聊天。此外,这将通过回复,特定用户或通道 ID 以及对 Slack API 的身份验证令牌进行响应,这确保了消息或回复 Slack 聊天的消息显示在特定频道上,从它发起的位置。作为示例,我们将使用聊天来加密或解密特定值。
例如,如果我们写 encrypt username[:]password,它将返回带有 base64 值的加密字符串。
类似地,如果我们写,聊天机器人将在解密编码的字符串后返回。decrypt 代码如下:
import json
import requests
import base64
from splunk_alexa import alexa
channl=””
token=””
resp=””
def set_data(Channel,Token,Response):
global channl,token,resp
channl=Channel
token=Token
resp=Response
def send_data(text):
global channl,token,res
print(channl)
resp = requests.post(“https://slack.com/api/chat.postMessage”,data='{“channel”:”‘+channl+'”,”text”:”‘+text+'”}’,headers={“Content-type”: “application/json”,”Authorization”: “Bearer “+token},verify=False)

def channel_connect(text):
global channl,token,resp
try:
print(text)
arg=text.split(‘ ‘)
print(str(arg))
path=arg[0].lower()
print(path in [“decode”,”encode”])
if path in [“decode”,”encode”]:
print(“deecode api”)
else:
result=alexa(arg,resp)
text=””
try:
for i in result:
print(i)
print(str(i.values()))
for j in i.values():
print(j)
text=text+’ ‘+j
#print(j)
if text==”” or text==None:
text=”None”
send_data(text)
return
except:
text=”None”
send_data(text)
return
decode=arg[1]
except:
print(“Please enter a string to decode”)
text=” argument cannot be empty”
send_data(text)
return
deencode(arg,text)

def deencode(arg,text):
global channl,token,resp
decode=arg[1]
if arg[1]==’–help’:
#print(“Sinput”)
text=”encode/decode ”
send_data(text)
return
if arg[0].lower()==”encode”:
encoded=base64.b64encode(str.encode(decode))
if ‘[:]’ in decode:
text=”Encoded string: “+encoded.decode(‘utf-8’)
send_data(text)
return
else:
text=”sample string format username[:]password”
send_data(text)
return
try:
creds=base64.b64decode(decode)
creds=creds.decode(“utf-8”)
except:
print(“problem while decoding String”)
text=”Error decoding the string. Check your encoded string.”
send_data(text)
return
if ‘[:]’ in str(creds):
print(“[:] substring exists in the decoded base64 credentials”)
# split based on the first match of “[:]”
credentials = str(creds).split(‘[:]’,1)
username = str(credentials[0])
password = str(credentials[1])
status = ‘success’
else:
text=”encoded string is not in standard format, use username[:]password”
send_data(text)
print(“the encoded base64 is not in standard format username[:]password”)
username = “Invalid”
password = “Invalid”
status = ‘failed’
temp_dict = {}
temp_dict[‘output’] = {‘username’:username,’password’:password}
temp_dict[‘status’] = status
temp_dict[‘identifier’] = “”
temp_dict[‘type’] = “”
#result.append(temp_dict)
print(temp_dict)
text=” “+username+” “+password
send_data(text)
print(resp.text)
print(resp.status_code)
return
此代码查询 Splunk 实例以查找与聊天机器人的特定聊天。聊天会要求任何 Loopback45 当前关闭的管理界面()。另外,在聊天中,用户可以询问管理接口所在的所有路由器 up。此英语响应将转换为 Splunk 查询,并根据 Splunk 的响应将状态返回到 Slack 聊天。
让我们看看执行动作来响应结果的代码,对 Slack 聊天:
from splunkquery import run
def alexa(data,resp):
try:
string=data.split(‘ ‘)
except:
string=data
search=’ ‘.join(string[0:-1])
param=string[-1]
print(“param”+param)
match_dict={0:”routers management interface”,1:”routers management loopback”}
for no in range(2):
print(match_dict[no].split(‘ ‘))
print(search.split(‘ ‘))
test=list(map(lambda x:x in search.split(‘ ‘),match_dict[no].split(‘ ‘)))
print(test)
print(no)
if False in test:
pass
else:
if no in [0,1]:
if param.lower()==”up”:
query=”search%20index%3D%22main%22%20earliest%3D0%20%7C%20dedup%20interface_name%2Crouter_name%20%7C%20where%20interface_name%3D%22Loopback45%22%20%20and%20interface_status%3D%22up%22%20%7C%20table%20router_name”
elif param.lower()==”down”:
query=”search%20index%3D%22main%22%20earliest%3D0%20%7C%20dedup%20interface_name%2Crouter_name%20%7C%20where%20interface_name%3D%22Loopback45%22%20%20and%20interface_status%21%3D%22up%22%20%7C%20table%20router_name”
else:
return “None”
result=run(query,resp)
return result
以下 Splunk 查询获取状态:
· 对于 UP 接口:查询如下:
index=”main” earliest=0 | dedup interface_name,router_name | where interface_name=”Loopback45″ and interface_status=”up” | table router_name
· 对于 DOWN 接口(除了以外的任何状态):查询如下:
index=”main” earliest=0 | dedup interface_name,router_name | where interface_name=”Loopback45″ and interface_status!=”up” | table router_name
让我们看看聊天机器人聊天的最终结果以及根据聊天记录发回的响应。
编码 / 解码示例如下:

正如我们在这里看到的,我们发送了一条 encode abhishek[:]password123 消息聊天。此聊天作为 POST 请求发送到 API,后者又将其加密到 base64 并使用添加的单词作为回复。在下一个聊天中,我们使用 decode 选项传递相同的字符串。这会通过解码来自 API 函数的信息进行响应,并使用用户名和密码回复 Slack 聊天。Encoded string: abhishekpassword123
让我们看一下 Splunk 查询聊天的示例:

在此查询中,我们已关闭 Loopback45 接口 rtr1。在我们通过 Python 脚本计划发现这些接口的过程中,数据现在位于 Splunk 中。当查询哪个管理接口(Loopback45)关闭时,它将回复 rtr1。松弛的聊天,On which routers the management interface is down 会将此传递给 API,在收到此有效负载后,它将运行 Splunk 查询以获取统计信息。返回值(在本例中为 rtr1)将作为聊天中的响应返回。
类似地,中,反向查询 On which routers the management interface is up,将查询的 Splunk 和最终共享回响应 rtr2,rtr3 和 rtr4(因为所有这些路由器接口是 UP)。
可以扩展此聊天用例,以确保使用简单聊天可以进行完整的端到端故障排除。可以使用各种后端功能构建大量案例,从问题的基本识别到复杂任务,例如基于已识别情况的补救。

退出移动版