我正在创建一个机器人,其中我必须发送一张带有从Microsoft Graph获得的图像的英雄卡。问题是我无法发送访问令牌以这种方式获取图像。
我在 CardImage 的构造函数中传递图像 URL。没有其他构造函数或函数可以修改它,因此我无法像往常一样获取带有令牌的图像,然后将其发送到 CardImage。
有没有办法将令牌作为 url 查询字符串传递?我知道不建议这样做,那么有没有其他方法可以完成此操作?感谢您的帮助
我不相信有办法做到这一点,除非您以某种方式拦截客户端中的http请求并添加Authorization: Bearer <token>
标头。
但是,MSGraph 示例使用了一种解决方法。
-
提示用户登录
-
使用令牌获取照片,并保留照片的 base64 字符串。
-
将 base64 字符串添加到
CardImage.Url
属性。- 它接受 base64 字符串,只要它的格式为:
"data:image/png;base64,<base64String>"
- 这个答案可能会对你这部分有所帮助
- 它接受 base64 字符串,只要它的格式为:
对于后代,每个步骤的相关代码
步骤 1
在对话框中构造函数中:
AddDialog(new OAuthPrompt(
nameof(OAuthPrompt),
new OAuthPromptSettings
{
ConnectionName = ConnectionName,
Text = "Please login",
Title = "Login",
Timeout = 300000, // User has 5 minutes to login
}));
第一步:
private async Task<DialogTurnResult> PromptStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
return await stepContext.BeginDialogAsync(nameof(OAuthPrompt), null, cancellationToken);
}
下一步:
private async Task<DialogTurnResult> LoginStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
// Get the token from the previous step. Note that we could also have gotten the
// token directly from the prompt itself. There is an example of this in the next method.
var tokenResponse = (TokenResponse)stepContext.Result;
if (tokenResponse != null)
{
await stepContext.Context.SendActivityAsync(MessageFactory.Text("You are now logged in."), cancellationToken);
return await stepContext.PromptAsync(nameof(TextPrompt), new PromptOptions { Prompt = MessageFactory.Text("Would you like to do? (type 'me', 'send <EMAIL>' or 'recent')") }, cancellationToken);
}
await stepContext.Context.SendActivityAsync(MessageFactory.Text("Login was not successful please try again."), cancellationToken);
return await stepContext.EndDialogAsync();
}
现在我们有了令牌。
步骤 2
// Gets the user's photo
public async Task<PhotoResponse> GetPhotoAsync()
{
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + _token);
client.DefaultRequestHeaders.Add("Accept", "application/json");
using (var response = await client.GetAsync("https://graph.microsoft.com/v1.0/me/photo/$value"))
{
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException($"Graph returned an invalid success code: {response.StatusCode}");
}
var stream = await response.Content.ReadAsStreamAsync();
var bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
var photoResponse = new PhotoResponse
{
Bytes = bytes,
ContentType = response.Content.Headers.ContentType?.ToString(),
};
if (photoResponse != null)
{
photoResponse.Base64String = $"data:{photoResponse.ContentType};base64," +
Convert.ToBase64String(photoResponse.Bytes);
}
return photoResponse;
}
}
步骤 3
public static string ImageToBase64()
{
var path = System.Web.HttpContext.Current.Server.MapPath(@"~imgstestpic.PNG");
Byte[] bytes = File.ReadAllBytes(path);
string base64String = Convert.ToBase64String(bytes);
return "data:image/png;base64," + base64String;
}
[...]
var imgUrl = ImageToBase64();
var cardImages = new List<CardImage>();
cardImages.Add(new CardImage(url: imgUrl));
var heroCard = new HeroCard
{
Title = "BotFramework Hero Card",
Subtitle = "Microsoft Bot Framework",
Text = "Build and connect intelligent bots to interact with your users naturally wherever they are," +
" from text/sms to Skype, Slack, Office 365 mail and other popular services.",
Images = cardImages,
Buttons = new List<CardAction> { new CardAction(ActionTypes.OpenUrl, "Get Started", value: "https://learn.microsoft.com/bot-framework") },
};
var attachment = heroCard.ToAttachment();
var message = MessageFactory.Attachment(attachment);
await context.PostAsync(message);