来自Bot框架的AwaitableAttachment FormFlow的Retreive文件?

时间:2018-06-19 07:28:18

标签: c# azure botframework bots

我正在为公司建立招聘机器人。这个机器人的主要任务是从候选人那里获取信息,包括他的简历以及通过电子邮件发送所有信息。

我正在使用FormFlow(基本)而不是对话框,这里是我获取文件的代码

[AttachmentContentTypeValidator(ContentType = "pdf")]
[Prompt("please, provide us your resume")]
public AwaitableAttachment file_CV;

[Prompt("Your email ?")]
public string email;

public static IForm<ProfileForm> BuildForm()
{
    return new FormBuilder<ProfileForm>()
                   .Message("thank you")
                   .Build();
}

如果我没有错,附件文件将转换为本地存储中的blob,但在生产中,如何检索此文件以通过电子邮件将其发送到电子邮件作业公司?使用azure存储可能吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

正如您在评论中提到的那样,用户提供的附件pdf文件似乎作为附件存储在渠道的Blob存储空间中。

如果要存储用户在自定义存储中提供的pdf文件(例如Azure Blob存储),则可以基于ContentUrl访问附件并将其上传到验证功能中的Azure Blob存储。

代码段:

.Field(nameof(file_CV),
validate: async (state, value) =>
{
    var val = (AwaitableAttachment)value;

    var url = val.Attachment.ContentUrl;
    var aname = val.Attachment.Name;

    HttpClient httpClient = new HttpClient();
    Stream filestrem = await httpClient.GetStreamAsync(url);
    httpClient.Dispose();

    var storageAccount = CloudStorageAccount.Parse("{storage_connect_string}");
    var blobClient = storageAccount.CreateCloudBlobClient();

    var cloudBlobContainer = blobClient.GetContainerReference("useruploads");
    await cloudBlobContainer.CreateIfNotExistsAsync();

    CloudBlockBlob blockBlob = cloudBlobContainer.GetBlockBlobReference(aname);

    blockBlob.UploadFromStream(filestrem);

    ((AwaitableAttachment)value).Attachment.ContentUrl = blockBlob.Uri.ToString();


    var result = new ValidateResult { IsValid = true, Value = value };
    return result;
})

测试结果:

enter image description here

答案 1 :(得分:0)

我为此创建了一个示例机器人here,因为它涉及程度相对较高。 重要代码在ImagesForm.cs中。 表单本身保持不变,但是在创建表单时,您需要确保包含onCompletion:

return new FormBuilder<ImagesForm>()
                    .Message("Welcome, please submit all required documents")
                    .OnCompletion(onFormCompleted)
                    .Build();

这将使您可以处理用户提交的回复。

要将信息转发到电子邮件,您必须创建从机器人到另一个帐户的主动电子邮件(这也意味着您必须确保已设置电子邮件频道

var botAccount = new ChannelAccount(name: $"{ConfigurationManager.AppSettings["BotId"]}", id: $"{ConfigurationManager.AppSettings["BotEmail"]}".ToLower()); //botemail is cast to lower so that it can be recognized as valid
            var userAccount = new ChannelAccount(name: "Name", id: $"{ConfigurationManager.AppSettings["UserEmail"]}");//all of these are additional fields within application settings
            MicrosoftAppCredentials.TrustServiceUrl(@"https://email.botframework.com/", DateTime.MaxValue); //a call to TrustServiceUrl is required to send a proactive message to a channel different from the one the user is actively using.
            var connector = new ConnectorClient(new Uri("https://email.botframework.com/" ));
            var conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
            IMessageActivity message = Activity.CreateMessageActivity();
            message.From = botAccount;
            message.Recipient = userAccount;
            message.Conversation = new ConversationAccount(id: conversationId.Id);
            message.Text = $"Resume recieved from {state.email.ToString()}"; //the actual body of the email
            message.Locale = "en-Us";


            message.Attachments = new List<Attachment>();
            message.Attachments.Add(state.file_CV.Attachment);

此后,您只需要将电子邮件发送到电子邮件频道

            try
            {
                await connector.Conversations.SendToConversationAsync((Activity)message);
            }
            catch (ErrorResponseException e)
            {
                Console.WriteLine("Error: ", e.StackTrace);
            }

注意 这将在本地主机上工作,因为附件包括一个ContentUrl,该内容指向http本地主机端点,而电子邮件通道需要一个https端点。确保您部署在Azure上以实际测试此功能。