【Day26】建立一个 Bing Search Bot

今天我们要来实作一个 Bing Search Chatbot。

建立一些档案

https://ithelp.ithome.com.tw/upload/images/20201011/20129689SZ0baPLr4o.jpg

在 requirements 输入

aiohttp
jsonpickle
botbuilder-core>=4.10.0

开始撰写程序码

复制贴上以下程序码至 config.py

import os

class DefaultConfig:
    """ Bot Configuration """
    PORT = 3978
    APP_ID = os.environ.get("MicrosoftAppId", "")
    APP_PASSWORD = os.environ.get("MicrosoftAppPassword", "")
    
    '''Bing Search API 的基本设定'''
    # (必需修改) 此KEY为Azure Portal上Bing Image API的KEY
    BING_SEARCH_API_KEY = '<贴上你的Bin Search KEY>'
    # (可修改) 使用Bing Image API所打的endpoint,可修改後面query的内容
    BING_IMAGE_SEARCH_API_ENDPOINT = "https://api.cognitive.microsoft.com/bing/v7.0/images/search"

复制贴上以下程序码至 app.py

from aiohttp import web
from aiohttp.web import Request, Response, json_response
from botbuilder.core import (
    BotFrameworkAdapterSettings,
    TurnContext,
    BotFrameworkAdapter
)
from botbuilder.core.integration import aiohttp_error_middleware
from botbuilder.schema import Activity, ActivityTypes

from bots import BingSearchBot
from config import DefaultConfig

import sys
import traceback
from datetime import datetime

CONFIG = DefaultConfig()
# Create adapter.
# See https://aka.ms/about-bot-adapter to learn more about how bots work.
SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
ADAPTER = BotFrameworkAdapter(SETTINGS)


# Catch-all for errors.
async def on_error(context: TurnContext, error: Exception):
    # This check writes out errors to console log .vs. app insights.
    # NOTE: In production environment, you should consider logging this to Azure
    #       application insights.
    print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr)
    traceback.print_exc()

    # Send a message to the user
    await context.send_activity("The bot encountered an error or bug.")
    await context.send_activity(
        "To continue to run this bot, please fix the bot source code."
    )
    # Send a trace activity if we're talking to the Bot Framework Emulator
    if context.activity.channel_id == "emulator":
        # Create a trace activity that contains the error object
        trace_activity = Activity(
            label="TurnError",
            name="on_turn_error Trace",
            timestamp=datetime.utcnow(),
            type=ActivityTypes.trace,
            value=f"{error}",
            value_type="https://www.botframework.com/schemas/error",
        )
        # Send a trace activity, which will be displayed in Bot Framework Emulator
        await context.send_activity(trace_activity)

ADAPTER.on_turn_error = on_error

# create bot
BOT = BingSearchBot()


# Listen for incoming requests on /api/messages
async def messages(req: Request) -> Response:
    # Main bot message handler.
    if "application/json" in req.headers["Content-Type"]:
        body = await req.json()
    else:
        return Response(status=415)

    activity = Activity().deserialize(body)
    auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""

    response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
    if response:
        return json_response(data=response.body, status=response.status)
    return Response(status=201)


APP = web.Application(middlewares=[aiohttp_error_middleware])
APP.router.add_post("/api/messages", messages)

if __name__ == "__main__":
    try:
        web.run_app(APP, host="localhost", port=CONFIG.PORT)
    except Exception as error:
        raise error

在 bots 的资料夹新增两个 .py 档
https://ithelp.ithome.com.tw/upload/images/20201011/20129689HCzriGaFyn.jpg

__init__.py 复制贴上以下程序码

from .bing_search_bot import BingSearchBot

__all__ = ["BingSearchBot"]

bing_search_bot.py 复制贴上以下程序码

from botbuilder.core import ActivityHandler, TurnContext, MessageFactory
from botbuilder.schema import ChannelAccount, Attachment

from config import DefaultConfig

import json
import requests
import urllib.request
import os

class BingSearchBot(ActivityHandler):
    # 首次加入的问候的讯息
    async def on_members_added_activity(self, members_added: list, turn_context: TurnContext):
        for member in members_added:
            if member.id != turn_context.activity.recipient.id:
                await turn_context.send_activity(
                    f"欢迎来到Bing API的机器人,传图片以图搜寻,传文字以文字搜寻 !")

    # 每一次对话都是由这里来处理
    async def on_message_activity(self, turn_context: TurnContext):
        image_url_list = []
        host_page_url_list = []
        host_page_name_list = []
        
        if turn_context.activity.text : 
            image_url_list, host_page_url_list, host_page_name_list = self.bing_image_api(turn_context.activity.text)
            for i in range(len(host_page_url_list)):
                await turn_context.send_activity(MessageFactory.content_url(url= image_url_list[i], content_type='image/jpg', text=host_page_name_list[i]))
                await turn_context.send_activity(MessageFactory.text(text= host_page_url_list[i]))
    
    def bing_image_api(self, query) : 
        image_url = []
        host_page_url = []
        host_page_name = []

        # Construct a request
        mkt = 'zh-tw'
        params = {'q': query, 'mkt': mkt}
        headers = {'Ocp-Apim-Subscription-Key': DefaultConfig.BING_SEARCH_API_KEY}
        
        try:
            response = requests.get(DefaultConfig.BING_IMAGE_SEARCH_API_ENDPOINT, headers=headers, params=params)
            response.raise_for_status()

            for i in range(3):
                image_url.append(response.json()['value'][i]['contentUrl'])       # 若要更改回传内容,可修改後面的索引
                host_page_url.append(response.json()['value'][i]['hostPageUrl'])
                host_page_name.append(response.json()['value'][i]['name'])
        except Exception as ex:
            raise ex
        
        return image_url, host_page_url, host_page_name

测试机器人


<<:  Day27 人物骨架 - 简介篇

>>:  2020it邦铁人赛-30天手把手的Vue.js教学 Day28 - 关心时事! 做个简单的COVID-19追踪app吧!(上)

33岁转职者的前端笔记-DAY 29 前端面试题目练习

经过几次的面试,发现在笔试的时候观念非常不熟悉 所以回家的时候自行找出答案增加基本知识 今天就来做个...

产品成长策略 - 安索夫矩阵

一家公司很难单靠一个产品来获利,就像 原来产品也有自己的生命历程 Product Life Cycl...

【课程推荐】2021/9/25-10/3 微服务架构设计与实作 – 使用 Java Spring 与 UML

课程目标 了解什麽是微服务的架构以及使用 UML 塑模呈现 从问题领域界定 Bounded Area...

我们的基因体时代-AI, Data和生物资讯 Day19-分析和处理基因变异的档案格式VCF的工具

上一篇我们的基因体时代-AI, Data和生物资讯 Day18-基因变异的档案格式VCF上一篇介绍当...

Day-21 RadioGroup

使用者可在一个RadioGroup底下,建立多个RadioButton。 而RadioGroup与C...