How to get contact's photo from exchange server - exchange-server

Based on this tutorial, I'm trying to get contacts photos
private String createPhoto() {
try {
AttachmentCollection attachments = contact.getAttachments();
for (Attachment attachment : attachments.getItems()) {
if (attachment instanceof FileAttachment) {
boolean isPhoto = ((FileAttachment) attachment).isContactPhoto();
if (isPhoto) {
attachment.load();
FileAttachment photo = contact.getContactPictureAttachment();
String filename = photo.getName() + ".jpg";
photo.load(new FileOutputStream(filename, true));
return filename;
}
}
}
} catch (Exception ex) {
LOGGER.info("" + ex);
}
return null;
}
However, attachments.getItems() is always an empty array.
On my mailbox, I have few contacts with photos, and I can receive them by calling URL https://companyname.exchange.com/EWS/Exchange.asmx/s/GetUserPhoto?email=name#company.exchange.com&size=HR360x360
Why I can't get a photo from the code?

On my mailbox, I have few contacts with photos, and I can receive them by calling URL https://companyname.exchange.com/EWS/Exchange.asmx/s/GetUserPhoto?email=name#company.exchange.com&size=HR360x360
That request gets the Userphoto which is stored in the (Source)Users Mailbox (or low res in ActiveDirectory) and made available by that operation.
Your code is trying to retrieve the ContactPhoto which can be stored as an attachment on Contacts in a UserMailbox.
So these are two separate things so which one are you dealing with ?, As you haven't shown it you need to make sure you ExchangeServerRequest Version is set to 2010 or greater as Contact photos aren't returned in 2007. You might also want to test quickly the contacts in Question with the EWS Editor https://ewseditor.codeplex.com/ that will allow you to get the objects and see if there is a ContactPhoto Attachments using EWS.

Related

Various errors using VisionServiceClient in XamarinForms

I am trying to create a simple Xamarin forms app which allows the user to browse for or take a photo and have azure cognitive services tag the photo using a custom vision model.
I am unable to get the client to successfully authenticate or find a resource per the error message in the exception produced by the VisionServiceClient. Am I missing something? What would be the correct values to use for the arguments to VisionServiceClient?
All keys have been removed from the below images, they are populated.
Exception thrown in VS2017:
'Microsoft.ProjectOxford.Vision.ClientException' in System.Private.CoreLib.dll
Call to VisionServiceClient:
private const string endpoint = #"https://eastus2.api.cognitive.microsoft.com/vision/prediction/v1.0";
private const string key = "";
VisionServiceClient visionClient = new VisionServiceClient(key, endpoint);
VisualFeature[] features = { VisualFeature.Tags, VisualFeature.Categories, VisualFeature.Description };
try
{
AnalysisResult temp = await visionClient.AnalyzeImageAsync(imageStream,
features.ToList(), null);
return temp;
}
catch(Exception ex)
{
return null;
}
VS Exception Error:
Azure Portal for cognitive services:
Custom Vision Portal:
It looks like you're confusing the Computer Vision and the Custom Vision APIs. You are attempting to use the client SDK for the former using the API key of the latter.
For .NET languages, you'll want the Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction NuGet package.
Your code will end up looking something like this:
ICustomVisionPredictionClient client = new CustomVisionPredictionClient()
{
ApiKey = PredictionKey,
Endpoint = "https://southcentralus.api.cognitive.microsoft.com"
};
ImagePrediction prediction = await client.PredictImageAsync(ProjectId, stream, IterationId);
Thank you to cthrash for the extended help and talking with me in chat. Using his post along with a little troubleshooting I have figured out what works for me. The code is super clunky but it was just to test and make sure I'm able to do this. To answer the question:
Nuget packages and classes
Using cthrash's post I was able to get both the training and prediction nuget packages installed, which are the correct packages for this particular application. I needed the following classes:
Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction
Microsoft.Azure.CognitiveServices.Vision.CustomVision.Prediction.Models
Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training
Microsoft.Azure.CognitiveServices.Vision.CustomVision.Training.Models
Endpoint Root
Following some of the steps Here I determined that the endpoint URL's only need to be the root, not the full URL provided in the Custom Vision Portal. For instance,
https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction/
Was changed to
https://southcentralus.api.cognitive.microsoft.com
I used both the key and endpoint from the Custom Vision Portal and making that change I was able to use both a training and prediction client to pull the projects and iterations.
Getting Project Id
In order to use CustomVisionPredictionClient.PredictImageAsync you need a Guid for the project id and an iteration id if a default iteration is not set in the portal.
I tested two ways to get the project id,
Using project id string from portal
Grab the project id string from the portal under the project settings.
For the first argument to PredictImageAsync pass
Guid.Parse(projectId)
Using the training client
Create a new CustomVisionTrainingClient
To get a list of <Project> use
TrainingClient.GetProjects().ToList()
In my case I only had a single project so I would just need the first element.
Guid projectId = projects[0].Id
Getting Iteration Id
To get the iteration id of a project you need the CustomVisionTrainingClient.
Create the client
To get a list of <Iteration> use
client.GetIterations(projectId).ToList()
In my case I had only a single iteration so I just need the first element.
Guid iterationId = iterations[0].Id
I am now able to use my model to classify images. In the code below, fileStream is the image stream passed to the model.
public async Task<string> Predict(Stream fileStream)
{
string projectId = "";
//string trainingEndpoint = "https://southcentralus.api.cognitive.microsoft.com/customvision/v2.2/Training/";
string trainingEndpoint = "https://southcentralus.api.cognitive.microsoft.com/";
string trainingKey = "";
//string predictionEndpoint = "https://southcentralus.api.cognitive.microsoft.com/customvision/v2.0/Prediction/";
string predictionEndpoint = "https://southcentralus.api.cognitive.microsoft.com";
string predictionKey = "";
CustomVisionTrainingClient trainingClient = new CustomVisionTrainingClient
{
ApiKey = trainingKey,
Endpoint = trainingEndpoint
};
List<Project> projects = new List<Project>();
try
{
projects = trainingClient.GetProjects().ToList();
}
catch(Exception ex)
{
Debug.WriteLine("Unable to get projects:\n\n" + ex.Message);
return "Unable to obtain projects.";
}
Guid ProjectId = Guid.Empty;
if(projects.Count > 0)
{
ProjectId = projects[0].Id;
}
if (ProjectId == Guid.Empty)
{
Debug.WriteLine("Unable to obtain project ID");
return "Unable to obtain project id.";
}
List<Iteration> iterations = new List<Iteration>();
try
{
iterations = trainingClient.GetIterations(ProjectId).ToList();
}
catch(Exception ex)
{
Debug.WriteLine("Unable to obtain iterations.");
return "Unable to obtain iterations.";
}
foreach(Iteration itr in iterations)
{
Debug.WriteLine(itr.Name + "\t" + itr.Id + "\n");
}
Guid iteration = Guid.Empty;
if(iterations.Count > 0)
{
iteration = iterations[0].Id;
}
if(iteration == Guid.Empty)
{
Debug.WriteLine("Unable to obtain project iteration.");
return "Unable to obtain project iteration";
}
CustomVisionPredictionClient predictionClient = new CustomVisionPredictionClient
{
ApiKey = predictionKey,
Endpoint = predictionEndpoint
};
var result = await predictionClient.PredictImageAsync(Guid.Parse(projectId), fileStream, iteration);
string resultStr = string.Empty;
foreach(PredictionModel pred in result.Predictions)
{
if(pred.Probability >= 0.85)
resultStr += pred.TagName + " ";
}
return resultStr;
}

Office.Interop how to find email using PR_SEARCH_KEY in sent Folder

I am using Outlook Object model (Interop) for my softawre.
Before I send email, I get and keep the PR_SEARCH_KEY of the email that we created.
If I want to find the email in sent folder using PR_SEARCH_KEY, how can I do that in c# using Office.Interop (not EWS or not redemption)?
I tried to find it from SentFolder.Items.Find(filter). But it does not work as the PR_SEARCH_KEY is binary.
Thanks !
public Outlook.MailItem FindEmailFromSentFolder(string emailId)
{
try
{
if (_sentFolderItems == null)
return null;
// find the sent mail from sent folder based on PR_Serach_Key
var filter = string.Format("#SQL=\"http://schemas.microsoft.com/mapi/proptag/0x300B0102\" = '{0}'",
emailId);
var item = _sentFolderItems.Find(filter);
if (item != null && item is Outlook.MailItem)
return item as Outlook.MailItem;
}
catch (Exception ex)
{
return null;
}
return null;
}
As you already noticed, OOM won't let you search for any binary property - you will need Extended MAPI (C++ or Delphi) or Redemption (any language).
Your best bet is to set some string property on the outgoing message and then look for it in the Sent Items folder.

How to add an Attachment to Outlook Mail from UWP App programmatically?

I am developing an UWP Application , i want to add a Attachment to outlook from UWP app programmatically
Request you to please me know if any alternatives are there.
Looking forward for your response.
You can use the share contract to send some data to the compliant applications (including outlook). It allows you to share some text and data with any compliant apps.
To activate the sharing, you just need to register to the DataRequested event and show the share UI:
DataTransferManager.GetForCurrentView().DataRequested += OnDataRequested;
DataTransferManager.ShowShareUI();
Then, in the event handler:
private async void OnDataRequested(DataTransferManager sender, DataRequestedEventArgs args)
{
var deferral = args.Request.GetDeferral();
try
{
args.Request.Data.Properties.Title = "Share Title"
args.Request.Data.Properties.Description = "Share some data/file";
var file = await ApplicationData.Current.TemporaryFolder.GetFileAsync("myFileToShare.xxx");
args.Request.Data.SetStorageItems(new IStorageItem[] { logFile });
}
catch
{
args.Request.FailWithDisplayText("Unable to share data");
}
finally
{
deferral.Complete();
sender.DataRequested -= OnDataRequested;
}
}
Once done, the system will show the share UI where the user will be able to select the app he want. This app will receive the sent data.
While #Vincent's answer is perfect when you want to use Share Contract, if you want to use Just Email and attach the File, Below is a simple Method that i use in one of my App.
internal async void ShowEmail(string body, string subject, StorageFile attachment)
{
EmailMessage email = new EmailMessage();
email.Subject = subject;
email.Body = body;
var stream = RandomAccessStreamReference.CreateFromFile(attachment);
email.SetBodyStream(EmailMessageBodyKind.Html, stream);
await EmailManager.ShowComposeNewEmailAsync(email);
}
Above method is a strip down of the example from Here

Send a mail from outlook by getting To list from SQl server

I am stuck with a issue from 5 days.
I need a way to attain following requirement.
mailing list is present in Database(SQL server)
I have a mail in Outlook
now i have to send mail to all the 200,000 mail ids in Database
**Note one mail can have only 200 mail IDs so
200,000/200=1000 mails **Note: this 200,000 count is not fixed it will decrease and increase>
like jhon#xyz.com will be present today , next day we may need not send to him
his name might be completely removed (so DL is not an option)
I need a way to automate this
All i have a sleep less nights and coffee cups on my desk
I work in ASP.net any PL which meets this need is fine.
I assume that you know how to create sql statement for what you need and how to retrieve data from database in .NET. This means that only issue is actually sending this from outlook.
Here is an article that describes this in detail and piece of code copied from there.
using System;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace OutlookAddIn1
{
class Sample
{
public static void SendEmailFromAccount(Outlook.Application application, string subject, string body, string to, string smtpAddress)
{
// Create a new MailItem and set the To, Subject, and Body properties.
Outlook.MailItem newMail = (Outlook.MailItem)application.CreateItem(Outlook.OlItemType.olMailItem);
newMail.To = to;
newMail.Subject = subject;
newMail.Body = body;
// Retrieve the account that has the specific SMTP address.
Outlook.Account account = GetAccountForEmailAddress(application, smtpAddress);
// Use this account to send the e-mail.
newMail.SendUsingAccount = account;
newMail.Send();
}
public static Outlook.Account GetAccountForEmailAddress(Outlook.Application application, string smtpAddress)
{
// Loop over the Accounts collection of the current Outlook session.
Outlook.Accounts accounts = application.Session.Accounts;
foreach (Outlook.Account account in accounts)
{
// When the e-mail address matches, return the account.
if (account.SmtpAddress == smtpAddress)
{
return account;
}
}
throw new System.Exception(string.Format("No Account with SmtpAddress: {0} exists!", smtpAddress));
}
}
}
What I would suggest is to skip using outlook unless that’s really necessary and send email by directly communicating with SMTP server.
Just search for “how to send email from C#” or something similar and you’ll find a ton of examples.

I want to send mail to custom domain email provider in windows mobile application

I want to send mail from my windows mobile application.
I have configured new mail account on windows mobile emulator 6.5.3. with custom domain email provider,
Now I am able to send and receive mails with that device,And I want to send mail from my code,when the button is clicked
A code to send mail by code is available here: Sending mail in Windows mobile application in Windows
If you need more assistance, please provide more details.
EDIT: to make it more clear:
First you have to create an outlook session and specify the account to use:
public sendMail(string sMailAccount)
{
session = new OutlookSession();
//eMail = new EmailMessage();
bool bFound = false;
foreach (Account acc in session.EmailAccounts)
{
System.Diagnostics.Debug.WriteLine(acc.Name);
if (acc.Name == sMailAccount)
bFound = true;
}
if (bFound)
account = session.EmailAccounts[sMailAccount];
if (account != null)
...
The above starts a seesion and uses the provided string sMailsAccount to find an existing defined mail account. The string has to match any of the mail accounts you already have ce´reated in pocket outlook.
Then, when you want to send an eMail, you use the existing session:
public bool send(string sImagePath)
{
if (account == null)
return false;
try
{
eMail = new EmailMessage();
rcp = new Recipient(_to);
eMail.To.Add(rcp);
eMail.Subject = "Visitenkarten";
eMail.BodyText = "VCard " + DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString() + "\r\nsent from eMDI2Mail";
attachement = new Attachment(sImagePath);
eMail.Attachments.Add(attachement);
eMail.Send(account);
//account.Send(eMail);
if (this._syncImmediately)
{
if (this.account != null)
Microsoft.WindowsMobile.PocketOutlook.MessagingApplication.Synchronize(this.account);
}
return true;
}
...
The above code creates a new eMail, attaches a file and sends the eMail immediately or lets outlook decide, wehn to send (at a specified interval). The eMail is send immediately, if Synchronize function is used.
Makes it more clear?

Resources