chandra
chandra

Reputation: 85

How to send attachment in bot framework in web embedded bot using c#

I want to send a csv file attachment to to user in bot. I am using the Microsoft bot framework C# bot builder SDK, using the web chat channel. I've the following to send a csv file to the user:

var csvPath = "D://ProjecteFile/Results.csv";
//Attachment attachment = new Attachment();
//attachment.ContentType = "text/csv";
//attachment.ContentUrl = csvPath;
//attachment.Name = "click this link to get server report";
//return attachment;

I also tried using a hero card

var heroCard = new HeroCard {
    Title = "Click to download Report",
        Buttons = new List < CardAction > {
            new CardAction(ActionTypes.OpenUrl, "Get Started", value: "file://L-156222101/ProjectFile)")
        };

    return heroCard.ToAttachment();
}

Is there any way for my bot to send a csv file to a user by via web chat?

Upvotes: 1

Views: 3642

Answers (3)

protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
    {
        //img and excel is special keyword which provide image or excel
        //Get message reply use getmsg method
        switch (turnContext.Activity.Text)
        {
            case "img":
                await turnContext.SendActivityAsync(MessageFactory.Attachment(GetImg()), cancellationToken);
                break;
            case "excel":
                await turnContext.SendActivityAsync(MessageFactory.Attachment(GetImg()), cancellationToken);
                break;
            default:
                await turnContext.SendActivityAsync(MessageFactory.Text(GetMsg(turnContext.Activity.Text)), cancellationToken);
                break;
        }

    }

    private Attachment GetImg()
    {
        var imagePath = Path.Combine(Environment.CurrentDirectory, @"bin\Debug\img.png");
        var imageData = Convert.ToBase64String(File.ReadAllBytes(imagePath));

        return new Attachment
        {
            Name = @"img.png",
            ContentType = "image/png",
            ContentUrl = $"data:image/png;base64,{imageData}",
        };
    }

Upvotes: -1

Fei Han
Fei Han

Reputation: 27793

It seems that your csv file is stored in your project folder and you’d like to send it as attachment from your bot to web client user. I use Attachments API to upload it and then send it to user, which works for me, you can refer to it.

Get uploaded attachment and send to user:

var replymes = context.MakeMessage();

Attachment attachment = null;
attachment = await GetUploadedAttachmentAsync(replymes.ServiceUrl, replymes.Conversation.Id);

replymes.Attachments.Add(attachment);

await context.PostAsync(replymes); 

GetUploadedAttachmentAsync:

private static async Task<Attachment> GetUploadedAttachmentAsync(string serviceUrl, string conversationId)
{
    var imagePath = System.Web.HttpContext.Current.Server.MapPath(@"~\csv_files\Results.csv");

    using (var connector = new ConnectorClient(new Uri(serviceUrl)))
    {
        var attachments = new Attachments(connector);
        var response = await attachments.Client.Conversations.UploadAttachmentAsync(
            conversationId,
            new AttachmentData
            {
                Name = "Results.csv",
                OriginalBase64 = File.ReadAllBytes(imagePath),
                Type = "text/csv"
            });

        var attachmentUri = attachments.GetAttachmentUri(response.Id);

        return new Attachment
        {
            Name = "Results.csv",
            ContentType = "text/csv",
            ContentUrl = attachmentUri
        };
    }
}

Test in Web Chat:

enter image description here

Note: as far as I know, specify the path of the file that is stored in local folder or shared network folder and directly send as attachment to user, which are not supported in bot.

Upvotes: 1

Anita George
Anita George

Reputation: 1153

You can achieve this using a herocard. The problem with your code is that you are not specifying the filename along with the location i.e if your filename is ProjectFile then the value in the button must contain ProjectFile.csv

The best approach is to add the file to a folder in your project and add the reference in the value of the Card Action in the button.

eg:

    Attachment attachment = new HeroCard
    {
        Title = "Click to download Report",
        Buttons = new List<CardAction>()
        {
            new CardAction()
            {
                Title = "Get Started",
                Type = ActionTypes.OpenUrl,
                Value = "D:\\ProjecteFile\\Results.csv"
            }
         }
    }.ToAttachment();

    var reply = context.MakeMessage();
    reply.Attachments.Add(attachment);
    await context.PostAsync(reply);

Upvotes: 3

Related Questions