I want my bot to send a PDF file to the user. I have the PDF as a base64 string and tried to send it through an attachment:
Attachment attachment1 = new Attachment();
attachment1.Name = "name.pdf";
attachment1.ContentType = "application/pdf";
attachment1.ContentUrl = "data:application/pdf;base64," + base64String;
var m = context.MakeMessage();
m.Attachments.Add(attachment1);
m.Text = "File";
await context.PostAsync(m);
Within the emulator, it just doesn't work but in the channels Telegram and Facebook (which I need), the bot just outputs an error...
Has someone already succeed in it?
Note: Using an HTTP address works fine, but I need to use the base64 string
As this method in botframework call sendDocument method of Telegram, and this method in its document property get http url or a file_id, so you can't pass base64String to this method as a valid document type.
You can follow the valid type of the document passing into the telegram in this link (also, see the following image).
The pdf file must be embedded resource. Hope it help.
if (this.channelid == "telegram")
{
var url = string.Format("https://api.telegram.org/bot{0}/sendDocument", Settings.tokentelegram);
Assembly _assembly;
Stream file;
using (var form = new MultipartFormDataContent())
{
form.Add(new StringContent(this.chat_id, Encoding.UTF8), "chat_id");
_assembly = Assembly.GetExecutingAssembly();
file = _assembly.GetManifestResourceStream("Namespace.FolderResourses.name.pdf");
form.Add(new StreamContent(file), "document", "name.pdf");
using (var client = new HttpClient())
{
await client.PostAsync(url, form);
}
}
}
Related
I am creating a web api to allow download files through POST. There is no need for UI. I am sending Byte array along with the Filename in a JSON as follows.
{
"FileName": "xxxyyyzzz.pdf",
"FileType": "Pricing",
"FileID": 12457,
"ContentInByteArray":
"JVBERi0xLjMNCiXi48QoNCnN0YXJ0eHJlZg0KMjcxNA0KJSVFT0YNCg==",
"ExceptionMessage": ""
}
The File content is actually converted into Byte array and set to "ContentInByteArray". Is this a good approach. Or Do I need any improvisation.
Please suggest.
You use send byte[] array when you need post file or image content or may be token content and handle them at API.
var request = new SomePostRequest
{
Id = 1,
Content = File.ReadAllBytes(filename); // read content file to byte[]
};
jsonSerializer.Serialize(bson, request);
var client = new HttpClient
{
BaseAddress = new Uri("http://www.server.com")
};
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/bson"));
var byteArrayContent = new ByteArrayContent(stream.ToArray());
byteArrayContent.Headers.ContentType = new MediaTypeHeaderValue("application/bson");
var result = await client.PostAsync(
"api/upload", byteArrayContent);
As the title, I want to let user click to open a file in browser which is created by Bot. I'm using webChat.
The code is what I have tried.
In botframework-emulator, if I click the link, the CSV file will open in the browser.
But in the webChat, it will request user to download, not open in the browser.
var aaa = await GetCSVAttachmentAsync(replymes.ServiceUrl, replymes.Conversation.Id);
foreach(var aa in aaa)
replymes.Attachments.Add(aa);
await context.PostAsync(replymes);
private async Task<IList<Attachment>> GetCSVAttachmentAsync(string serviceUrl, string conversationId)
{
string str = "this is a text CSV";
byte[] array = Encoding.GetEncoding("shift_jis").GetBytes(str);
using (var connector = new ConnectorClient(new Uri(serviceUrl)))
{
var attachments = new Attachments(connector);
var response = await attachments.Client.Conversations.UploadAttachmentAsync(
conversationId,
new AttachmentData
{
Name = "userinfo.csv",
OriginalBase64 = array,
Type = "text/csv"
});
message.Add(new Attachment
{
Name = "userinfo.html",
ContentType = "text/html",
ContentUrl = response.Id
});
return message;
}
}
To solve this problem, I also tried storageV2. But it seems the URI can't be accessed directly.
I still couldn't figure it out without creating a real file.
But instead of using storage V2, I can solve the problem. The thought is as below.
Let the bot create a file.
Upload it to Storage V2 using static website
Send the static website to user.
I have an endpoint that needs to accept a file upload and also some other information from the client request. With the following code I can upload the file successfully but can't seem to figure out how to read the other info.
I make a test request from Postman with the following form data:
image -- myimage.jpg -- of type File
email -- a#b.com -- of type Text
The backend code looks like this:
[HttpPost]
public async Task<HttpResponseMessage> SharePhoto()
{
try
{
var provider = new MultipartMemoryStreamProvider();
var data = await Request.Content.ReadAsMultipartAsync(provider);
// this is how I get the image which I am succesfully passing to EmailService
var item = (StreamContent)provider.Contents[0];
using (var stream = new MemoryStream())
{
await item.CopyToAsync(stream);
String emailAddress;
EmailService.SendSharedPhoto(emailAddress, stream);
return Request.CreateResponse();
}
}
catch
{
// do stuff
}
}
In this example I am able to access provider.Contents[1] but can't seem to be able to get the value from it into emailAddress. I'm thinking it may be possible to use the same trick as the await item.CopyToASync(stream) from the image upload, but I'm hoping I can get a simpler solution to that. Any ideas?
I just barely answered a very similar question to this yesterday. See my answer here complete with sample controller code.
The method I ended up using is:
If the form elements are strings (and it worked for me since the mobiel frontend took responsability for input data) you can do this:
var streamContent = (StreamContent)provider.Contents[1];
var memStream = new MemoryStream();
await streamContent.CopyToAsync(memStream);
var actualString = Encoding.UTF8.GetString(x.ToArray());
If however the field needs to represent a collection of items, like for example the email list: ["a#b.com", "x#c.com"], etc a JavaScriptSerializer can be user, like so:
var streamContent = (StreamContent)provider.Contents[1];
var emailAddresses = await str.ReadAsStringAsync();
var jsSerializer = new JavaScriptSerializer();
var deserializedData = jsSerializer.Deserialize<string[]>(emailAddresses);
Note that this is nowhere near safe, though it is few lines of code and happens to work.
I want to upload an image from the gallery or live pic (camera capture task) with some params; x = "some string", y = "some string", z = "some integer" and uploadimage = name of file tag in form.
Can anyone please help me?
Uploading image for WP8 was pain to setup. Many of the examples I follow was outdated and this took me days to research and finally got one to work. There are a few ways to upload:
1) Convert the image to a string and then you can send the image converted string via HTTP request. I've used this approach for Android, but haven't tried it for WP.
2) Upload the image via FTP and the text data via HTTP.
You have 3 choices to upload any File to server.
Convert file into Stream - recommend way
Convert file into ByteArray
Convert file into String
After that you can use HttpClient package make a POST request to server. Here is the code to demonstrate FileUpload by converting it into Stream.
Code:
public async void methodToUploadFile()
{
StorageFile file = await StorageFile.GetFileFromPathAsync("Assets/MyImage.png");
// var fileBytes = await GetBytesAsync(file);
HttpClient client = new HttpClient();
// give the server URI here
Uri requestUri = new Uri("Full Server URI", UriKind.Absolute);
MultipartFormDataContent formdata = new MultipartFormDataContent();
formdata.Add(new StringContent("some string"), "x");
formdata.Add(new StringContent("some string"), "y");
formdata.Add(new StringContent("some integer"), "z");
formdata.Add(new StreamContent(await file.OpenStreamForReadAsync()), "file", "MyImage.png");
// formdata.Add(new ByteArrayContent(fileBytes), "file", "MyImage.png");
// Make a POST request here
var res = await client.PostAsync(requestUri, formdata);
}
Hope this helps..!
We are trying to upload image to Twitter via silverlight code in WP7. We are able to post the message but not the image.
We tried all including download of their library but not getting the hint.
In following link,
https://dev.twitter.com/docs/api/1/post/statuses/update_with_media
there is one point which we are not able to set.
"Unlike POST statuses/update, this method expects raw multipart data. Your POST request's Content-Type should be set to multipart/form-data with the media[] parameter "
I am not getting it how to put it.
Can anyone please guide me or provide sample for image upload?
If your photo is called LoadedPhoto, you could create a memory stream from it
MemoryStream ms = new MemoryStream();
LoadedPhoto.SaveJpeg(ms, LoadedPhoto.PixelWidth, LoadedPhoto.PixelHeight, 0, 100);
Create OAuthCredentials object according to the authentication details you have acquired
var credentials = new OAuthCredentials
{
Type = OAuthType.ProtectedResource,
SignatureMethod = OAuthSignatureMethod.HmacSha1,
ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
ConsumerKey = Common.TwitterSettings.ConsumerKey,
ConsumerSecret = Common.TwitterSettings.ConsumerKeySecret,
Token = file.AccessToken,
TokenSecret = file.AccessTokenSecret,
Version = "1.0"
};
Create a RestClient and a RestRequest
var restClient = new RestClient
{
Authority = "https://upload.twitter.com"
};
var restRequest = new RestRequest
{
Credentials = credentials,
Path = "/1/statuses/update_with_media.xml",
Method = Hammock.Web.WebMethod.Post
};
Set the stream position to 0
ms.Position = 0;
Add fields to RestRequest
restRequest.AddField("status", message);
restRequest.AddFile("media[]", "ScreenShot.png", ms, "image/jpeg");
And then begin request
restClient.BeginRequest(restRequest, callback);
callback is a callback method for the request.
Taken from my blog post, see there for more details if you're interested.