Send Photo Telegram API - c#

I want to send a photo using the Telegram.Bot library, but it's not working!
Here is my code:
private void btnSendImage_Click(object sender, RoutedEventArgs e)
{
var Bot = new Telegram.Bot.Api(token);
Task<Telegram.Bot.Types.Update[]> res = Bot.GetUpdates();
List<string> users = GetIds();
foreach (var update in res.Result)
{
if (!users.Contains("" + update.Message.Chat.Id))
{
AddId("" + update.Message.Chat.Id);
}
}
users = GetIds();
foreach (var item in users)
{
if (item.Length > 0)
{
var rep = Bot.SendPhoto(Convert.ToInt32(item), txtImagePath.Text, txtMessage.Text);
}
}
}
and txtImagePath.text= "D:\Projects\Telegram Bot\Telegram Bot\bin\Debug\4.jpg";
I tested it with Bot.SendMessage and it worked fine, but I can't send a photo!

I used this code and it's worked!
var FileUrl = #"C:\\Users\\User\\Documents\\20160201_204055.jpg";
using (var stream = System.IO.File.Open(FileUrl, FileMode.Open))
{
FileToSend fts = new FileToSend();
fts.Content = stream;
fts.Filename = FileUrl.Split('\\').Last();
var test = await bot.SendPhoto("#channel Name or chat_id", fts, "My Text");
}

you need to pass a Stream to the function if you want to send an new image.
using (var stream = File.Open(txtImagePath.Text, FileMode.Open))
{
var rep = await Bot.SendPhoto(Convert.ToInt32(item), stream, txtMessage.Text);
}

Related

Microsoft Graph upload large files

I am developing an aplication that send and email with one or multiple attachments via Microsoft Graph, but when try to upload file send me an error: ": Invalid total bytes specified in the Content-Range header"
i asume that i must specifi Range Value in same where, but no idea.
This is my code:
private static async void SenMailUsingMicrosoftGraph(List<String>Destinations, List<String>Cc, string HidenCopy, string Body, string Title, List<FileInfo>Filess);
{
ClientSecretCredential credential = new ClientSecretCredential("MyTenantID", "MyClientId", "MyClientSecret");
List<Recipient> recipientsDestinatarios = new List<Recipient>();
List<Recipient> recipientsCopias = new List<Recipient>();
foreach (var c in Destinations)
{
recipientsDestinatarios.Add(
new Recipient
{
EmailAddress = new EmailAddress
{
Address = c
}
});
}
foreach (var mail in Cc)
{
recipientsCopias.Add(
new Recipient
{
EmailAddress = new EmailAddress
{
Address = mail
}
});
}
#endregion
var message = new Microsoft.Graph.Message
{
Subject = Title,
Body = new ItemBody
{
ContentType = BodyType.Html,
Content = Body
},
ToRecipients = recipientsDestinatarios
,
CcRecipients = recipientsCopias
,
BccRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress=new EmailAddress{Address=Hiden}
}
}
};
GraphServiceClient graphClient = new GraphServiceClient(credential);
#endregion
#region adjuntar ficheros
var msgResult = await graphClient.Users["myemail#mycompany.com"].MailFolders.Drafts.Messages
.Request()
.WithMaxRetry(9)
.AddAsync(message);
foreach (var Archivo in Filess)
{
var attachmentContentSize = Archivo.Length;
var attachmentItem = new AttachmentItem
{
AttachmentType = AttachmentType.File,
Name = Archivo.Name,
Size = attachmentContentSize,
};
//initiate the upload session for large files
var uploadSession = await graphClient.Users["myemail#mycompany.com"].Messages[msgResult.Id].Attachments
.CreateUploadSession(attachmentItem)
.Request()
.PostAsync();
var maxChunkSize = 1024 * 320;
var allBytes = System.IO.File.ReadAllBytes(Archivo.FullName);
using (var stream = new MemoryStream(allBytes))
{
stream.Position = 0;
LargeFileUploadTask<FileAttachment> largeFileUploadTask = new LargeFileUploadTask<FileAttachment>(uploadSession, stream, maxChunkSize);
await largeFileUploadTask.UploadAsync();
}
}
await graphClient.Users["myemail#mycompany.com"].Messages[msgResult.Id].Send().Request().PostAsync();
}
I try something like this:
var content = new System.Net.Http.Headers.ContentRangeHeaderValue(0,MyFile.Length-1,MyFile.Length);
but i dont now how to asign this content variable, i think that must go in the uploadSession but dont know how.
------------------------------------EDIT------------------------------
included a Picture where see that the size of the attachment is not zero

There is no file with ID 1. The file list may have changed Blazor

When I try to upload files from a list I get this error
"Error: There is no file with ID 1. The file list may have changed"
Its working when I attach one file but, when the list has more than one file, I get the error
The phone Im using to send is
calling function
foreach (var item in fileList)
{
var Enow = item.GetMultipleFiles();
foreach (var _item in Enow)
{
output = await _IfileUpload.Upload(_item, NewGuid.ToString());
}
}
called function
public async Task<string> Upload(IBrowserFile entry, string UploadGuid)
{
try
{
var path = Path.Combine(Directory.GetCurrentDirectory(), "Uploads/" + UploadGuid, entry.Name);
var _path = Path.Combine(Directory.GetCurrentDirectory(), "Uploads/" + UploadGuid);
if (!Directory.Exists(_path))
{
System.IO.Directory.CreateDirectory(_path);
}
Stream stream = entry.OpenReadStream();
FileStream fs = File.Create(path);
await stream.CopyToAsync(fs);
stream.Close();
fs.Close();
return path;
}
catch (Exception ex)
{
throw ex;
}
}
BlazorInputFile results in error: "There is no file with ID 1".
On re-add new files all previously created objects belonging to previous files aren't saved. Meantime the index starts with unsaved objects that no longer exist.
Saving files at each selection step gives an correct index.
The Chrome inside debugger indicates a problem in inputfile.js
I ran into similar problem and the solution was to create image data list that is populated each time new file is added from browser. In this case you can have proper grasp on data
private List<byte[]> _imageData = new List<byte[]>();
private void UploadFiles(InputFileChangeEventArgs e)
{
foreach (var file in e.GetMultipleFiles())
{
_files.Add(file);
_imageData.Add(GetImageBytes(file).Result);
}
}
private async Task<byte[]> GetImageBytes(IBrowserFile file)
{
var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
await using var fileStream = new FileStream(path, FileMode.Create);
await file.OpenReadStream(file.Size).CopyToAsync(fileStream);
var bytes = new byte[file.Size];
fileStream.Position = 0;
await fileStream.ReadAsync(bytes);
fileStream.Close();
File.Delete(path);
return bytes;
}
And finally
if (_imageData != null && _imageData.Count() > 0)
{
foreach (var photo in _imageData)
{
var result = await _uploadService.UploadImage(photo);
}
}
I would try this sample from the [docs][1]
<h3>Upload PNG images</h3>
<p>
<InputFile OnChange="#OnInputFileChange" multiple />
</p>
#if (imageDataUrls.Count > 0)
{
<h4>Images</h4>
<div class="card" style="width:30rem;">
<div class="card-body">
#foreach (var imageDataUrl in imageDataUrls)
{
<img class="rounded m-1" src="#imageDataUrl" />
}
</div>
</div>
}
#code {
IList<string> imageDataUrls = new List<string>();
private async Task OnInputFileChange(InputFileChangeEventArgs e)
{
var maxAllowedFiles = 3;
var format = "image/png";
foreach (var imageFile in e.GetMultipleFiles(maxAllowedFiles))
{
var resizedImageFile = await imageFile.RequestImageFileAsync(format,
100, 100);
var buffer = new byte[resizedImageFile.Size];
await resizedImageFile.OpenReadStream().ReadAsync(buffer);
var imageDataUrl =
$"data:{format};base64,{Convert.ToBase64String(buffer)}";
imageDataUrls.Add(imageDataUrl);
}
}
}

How can I access all of my google spreadsheet ID's?

I'm fairly new to coding and c#. I'm building an app that accesses google spreadsheets via an API, I turn this data into XML, zip it and write it to a stream. It works fine, but instead of adding every spreadsheet ID manually to my list I want to make another API call that will retrieve every ID in my google sheets account so that I can store them to a list and update it every time I run the app.
I'm banging my head off a wall looking for answers but I think this is not available via a sheets API but maybe through the drive API??, any help would be greatly appreciated, I'm not looking for anyone to write my code, but please point me in the right direction, or am I trying to do something that cannot be done?
public class GoogleSheetsReader
{
private string apiKey;
public Stream OutStream { get; set; }
List<string> SpreadSheetIdList { get; set; }
public GoogleSheetsReader(string apiKey)
{
this.apiKey = apiKey;
}
public Stream Main()
{
SheetsService sheetsService = new SheetsService(new BaseClientService.Initializer
{
HttpClientInitializer = GetCredential(),
ApplicationName = "My Project To XML",
ApiKey = apiKey,
});
using (MemoryStream memory = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(memory, ZipArchiveMode.Create))
{
SpreadSheetIdList = new List<string>(); // not the best place for the list, just testing funtionality
SpreadSheetIdList.Add("1oZlfj6XZOrPs9Qti9K9iKL6itZChM8dlwwJFSvBNzUc");
SpreadSheetIdList.Add("1oU3sjd7QoOgQ2PvmC7NxciyM1MRXns6-Z9vMayFgOjU");
foreach (var spreadSheetId in SpreadSheetIdList)
{
var ssRequest = sheetsService.Spreadsheets.Get(spreadSheetId);
Data.Spreadsheet service = ssRequest.Execute();
foreach (var sheet in service.Sheets)
{
var sheetName = sheet.Properties.Title;
SpreadsheetsResource.ValuesResource.GetRequest request = sheetsService.Spreadsheets.Values.Get(spreadSheetId, sheetName);
SpreadsheetsResource.GetRequest requestForSpreadSheet = sheetsService.Spreadsheets.Get(spreadSheetId);
requestForSpreadSheet.Ranges = sheetName;
Data.Spreadsheet response1 = requestForSpreadSheet.Execute();
var spreadSheetName = response1.Properties.Title;
Data.ValueRange response = request.Execute();
ZipArchiveEntry entry = zip.CreateEntry($"{spreadSheetName}\\{sheetName}.xml");
using (Stream ZipFile = entry.Open())
{
byte[] data = Encoding.ASCII.GetBytes(SchemaMaker(response)); // SchemaMaker converts my sheet data to required xml format
ZipFile.Write(data, 0, data.Length);
}
}
}
}
OutStream = new MemoryStream(memory.ToArray());
}
return OutStream;
}
public string SchemaMaker(ValueRange _param)
{
var result = "<TABLE>";
var headers = _param.Values[0];
for (int i = 1; i < _param.Values.Count; i++)
{
result = result + "<ROW>";
for (int j = 0; j < _param.Values[i].Count; j++)
{
result = result + $"<{headers[j]}>{_param.Values[i][j]}</{headers[j]}>";
}
result = result + "</ROW>";
}
result = result + "</TABLE>";
var element = XElement.Parse(result);
var settings = new System.Xml.XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;
settings.NewLineOnAttributes = true;
var xmlFormat = element.ToString();
return xmlFormat;
}
public static UserCredential GetCredential()
{
string[] Scopes = { SheetsService.Scope.SpreadsheetsReadonly };
return null;
}
}

Cannot access disposed object application connecting to WebAPI

I have content of video and object being created an pass into a http client web api. When ever I pass the image to the client it works find it gets to the post method, but when it comes to the video the client has trouble posting the video. I checked the video size length to make sure it meets the content length and it well under the specific ranges. The error that I receive is that the object has been disposed. If you look at the code the object is never disposed.
Here's the code on the app
public async Task<bool> AddToQueueAsync(Incident i, ContentPage page, MediaFile file)
{
HttpResponseMessage result = null;
Uri webserviceURL = i.IncidentType == IncidentType.Trooper ? trooperURL : gspURL;
var fileStream = File.Open(file.Path, FileMode.Open);
try
{
using (var client = new HttpClient())
{
using (fileStream)
{
using (var stream = new StreamContent(fileStream))
{
using (var content = new MultipartFormDataContent("----MyBoundary"))
{
if(i.MediaType == "Video")
{
content.Add(stream,"file", Guid.NewGuid().ToString() + ".mp4");
}
else
{
content.Add(stream, "file", Guid.NewGuid().ToString() + ".png");
}
content.Add(new StringContent(JsonConvert.SerializeObject(i)), "metadata");
result = await client.PostAsync(webserviceURL, content);
}
}
}
}
Here is the code on the web api:
[HttpPost]
public IHttpActionResult StarGSPDATA() {
try {
if(!Request.Content.IsMimeMultipartContent()) {
Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
starGSPDATAinfo suspicousInfo;
string homeDir = AppDomain.CurrentDomain.BaseDirectory;
string dir = $"{homeDir}/uploads/";
Directory.CreateDirectory(dir);
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
if(HttpContext.Current.Request.Form.Count > 0) {
suspicousInfo = MetaDataFromRequest(HttpContext.Current.Request.Form);
} else {
suspicousInfo = new starGSPDATAinfo();
}
if(file != null && file.ContentLength > 0) {
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(dir, fileName);
suspicousInfo.MediaFilePath = fileName;
try {
file.SaveAs(path);
} catch(Exception e) {
Console.WriteLine($"not saving: {e.ToString()}");
}
} else {
throw new HttpResponseException(
new HttpResponseMessage(
HttpStatusCode.NoContent));
}
CleanData(suspicousInfo);
db.starGSPDATAinfoes.Add(suspicousInfo);
db.SaveChanges();
return Created("http://localhost:50641/api/StarGSPDATA/", JsonConvert.SerializeObject(suspicousInfo));
} catch(Exception e) {
return InternalServerError(e);
}
}
It works for an image but not for a video Please help thank you!
Here is a picture of the error

Operation is not valid due to the current state of the object

i am beginning in develop winphone and nokia imaging sdk. i have two function.
firstly, i call the function below to change image to gray color
private async void PickImageCallback(object sender, PhotoResult e)
{
if (e.TaskResult != TaskResult.OK || e.ChosenPhoto == null)
{
return;
}
using (var source = new StreamImageSource(e.ChosenPhoto))
{
using (var filters = new FilterEffect(source))
{
var sampleFilter = new GrayscaleFilter();
filters.Filters = new IFilter[] { sampleFilter };
var target = new WriteableBitmap((int)CartoonImage.ActualWidth, (int)CartoonImage.ActualHeight);
var renderer = new WriteableBitmapRenderer(filters, target);
{
await renderer.RenderAsync();
_thumbnailImageBitmap = target;
CartoonImage.Source = target;
}
}
}
SaveButton.IsEnabled = true;
}
then i call function to change image to binary color
private async void Binary(WriteableBitmap bm_image)
{
var target = new WriteableBitmap((int)CartoonImage.ActualWidth, (int)CartoonImage.ActualHeight);
MemoryStream stream= new MemoryStream();
bm_image.SaveJpeg(stream, bm_image.PixelWidth, bm_image.PixelHeight, 0, 100);
using (var source = new StreamImageSource(stream))
{
using (var filters = new FilterEffect(source))
{
var sampleFilter = new StampFilter(5, 0.7);
filters.Filters = new IFilter[] { sampleFilter };
var renderer1 =new WriteableBitmapRenderer(filters, target);
{
await renderer1.RenderAsync();
CartoonImage.Source = target;
}
}
}
}
but when it run to " await renderer1.RenderAsync();" in the second function, it doesn't work. How can i solve it. And you can explain for me about how "await" and "async" work ?
thank you very much!
I'm mostly guessing here since I do not know what error you get, but I'm pretty sure your problem lies in setting up the source. Have you made sure the memory stream position is set to the beginning (0) before creating an StreamImageSource?
Try adding:
stream.Position = 0;
before creating the StreamImageSource.
Instead of trying to create a memory stream from the writeable bitmap I suggest doing:
using Nokia.InteropServices.WindowsRuntime;
...
using (var source = new BitmapImageSource(bm_image.AsBitmap())
{
...
}

Categories