我正在使用Bot Framework v4 SDK。我正在尝试将通过bot上传到Microsoft Teams的图片下载到一个临时目录中,然后使用该图片。我之所以愿意这样做,是因为我需要拍摄用户附加到聊天中的照片,然后将其放入文档中,然后将文档返回给用户。当我在模拟器上运行它时,此方法有效,但是一旦该机器人进入了Teams,我就会出错。
我通过附件提示提示用户输入照片:
return await stepContext.PromptAsync(
"imagePrompt",
new PromptOptions
{
Prompt = MessageFactory.Text("Please attach a picture."),
});
从stepContext.Result中获取附件:
List<Attachment> contextAttachmentResult = (List<Attachment>)stepContext.Result;
确定文件的托管位置
var remoteFileUrl = contextAttachmentResult[0].ContentUrl;
设置系统临时目录的路径
var tempImagePath = Path.Combine(Path.GetTempPath(), contextAttachmentResult[0].Name);
并尝试使用WebClient
using (var webClient = new WebClient())
{
webClient.Headers.Add("User-Agent", "Other");
webClient.Headers.Add("Authorization", userProfile.Token);
webClient.DownloadFile(remoteFileUrl, tempImagePath);
}
我尝试将令牌放入从OAuthPrompt
获得的令牌中,但仍然收到403。当我尝试下载403时,它就出现了。我认为这是SharePoint问题,是因为如果我打印出remoteFileUrl
,我会得到https://company-my.sharepoint.com/personal/my_name/Documents/Microsoft Teams Chat Files/someImage.png
堆栈跟踪的开始是:
System.Net.WebException: The remote server returned an error: (403) FORBIDDEN. at System.Net.HttpWebRequest.GetResponse() at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream) at System.Net.WebClient.DownloadFile(Uri address, String fileName)
编辑:
根据Mick的评论,我尝试以这种方式使用ConnectorClient
(并尝试了两种不同的下载方式):
using (var connectorClient = new ConnectorClient(new Uri(stepContext.Context.Activity.ServiceUrl, MYAPPID, MYAPPPASSWORD)))
{
var token = await (connectorClient.Credentials as MicrosoftAppCredentials).GetTokenAsync();
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(contextAttachmentResult[0].ContentType));
var byteArray = await httpClient.GetByteArrayAsync(remoteFileUrl);
}
using (var webClient = new WebClient())
{
webClient.Headers.Add("User-Agent", "Other");
webClient.Headers.Add("Authorization", token);
webClient.DownloadFile(remoteFileUrl, siteReviewFile1ImagePath);
}
}
但是即使我已将连接器设置为使用我的appId和appPwd System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at System.Net.Http.HttpClient.d__30.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at IBIBot.Dialogs.SiteReviewSpace.SiteReviewDialog.<>c__DisplayClass4_0.<<-ctor>b__2>d.MoveNext() in
我仍然对如何获得此下载感到困惑
答案 0 :(得分:1)
不使用Attachment.ContentUrl而是使用Attachment.Content.DownloadUrl解决此问题。 downloadurl是预先授权的下载,因此不需要任何载体或授权标头。 我的代码如下所示:
var remoteFileUrl = ((JObject)contextAttachmentResult[0].Content)["downloadUrl"].ToString();
using (var webClient = new WebClient())
{
webClient.DownloadFile(remoteFileUrl, someFileLocationPath);
}