online.kosen-career.tech
こちらのイベントでそれっぽいAsureBotを作ったのでその手順を備忘録。
基本的な環境構築からオウム返しBotまでは以下を参照。
qiita.com
無料で使えるそれっぽいAPIを探したところA3RTというものがリクルートから提供されていたので、これをBotに組み込むことを目標とする。
a3rt.recruit-tech.co.jp
EchoBot.csの初期状態を読むと
- OnMessageActivityAsyncでメッセージ送信時の反応
- OnMembersAddedAsyncで接続時の最初のメッセージ
を行っていることが分かる。
なので基本的にはOnMessageActivityAsyncの方を拡張していくような形。今回はBot上で画像を扱ってみたかったこともあり、ImageSearchAPIを使ってみた。
Image Search API | PRODUCT | A3RT
結果画像の送信はこちらのプログラムを参考にして実装した。
メッセージにメディアを追加する - Bot Service | Microsoft Docs
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Schema;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net;
using System.IO;
namespace Microsoft.BotBuilderSamples.Bots
{
public class EchoBot : ActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
var replyText = $"{turnContext.Activity.Text}";
string search_word = replyText;
WebRequest request = WebRequest.Create("https://api.a3rt.recruit-tech.co.jp/image_search/v1/search_by_text?apikey=AAAAAAAAAAAAAAAAAAAAAAAA&query=" + search_word);
WebResponse response = request.GetResponse();
using (Stream dataStream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
string jsonString = JsonConvert.SerializeObject(responseFromServer);
JObject deserial = (JObject)JsonConvert.DeserializeObject(responseFromServer);
string send_img = deserial["result"]["img"][0]["url"].ToString();
IMessageActivity reply = null;
reply = MessageFactory.Text("This is an inline attachment.");
reply.Attachments = new List<Attachment>() { GetInternetAttachment(send_img) };
await turnContext.SendActivityAsync(reply, cancellationToken);
}
response.Close();
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
var welcomeText = "Hello and welcome!";
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(MessageFactory.Text(welcomeText, welcomeText), cancellationToken);
}
}
}
private static Attachment GetInternetAttachment(string img_url)
{
return new Attachment
{
Name = @"Resources\architecture-resize.jpg",
ContentType = "image/jpg",
ContentUrl = img_url,
};
}
}
}
これを実行してみるとこんな感じ

画像の数には限りがあるみたいで、見当違いな結果になることも多いが、キーワード次第でそれっぽい結果を返す。
今はJson内の1つ目の画像URLを参照しているが、全部表示or最も類似するものを推定みたいなことが出来るといいかもしれない。
C# による JSON 相互変換 (Json.NET 利用) - clock-up-blog
基本的に他のAPIもリクエストするURLと受け取ったJsonの読み方を変えてやることでほぼ全部実装可能。必要に応じて組み合わせて見てほしい。