I need to get all the emails that have a specific category name, how would I do this?
Right now I have this:
var col = new List<SearchFilter>();
col.Add(new SearchFilter.ContainsSubstring(ItemSchema.Categories, "Processed"));
var filter = new SearchFilter.SearchFilterCollection(LogicalOperator.Or, col.ToArray());
FindItemsResults<Item> findResults = service.FindItems(
WellKnownFolderName.Inbox,
filter,
new ItemView(10)
);
But that gives me a Microsoft.Exchange.WebServices.Data.ServiceResponseException that says {"The Contains filter can only be used for string properties."}
How would I do it?
AFAIK as of Exchange 2010, category is a multi value field so it does not work with search filters. However, you can search categories using AQS. The following code should do the trick.
ExchangeService service = GetService();
var iv = new ItemView(1000);
string aqs = "System.Category:Processed";
FindItemsResults<Item> searchResult = null;
do
{
searchResult = service.FindItems(WellKnownFolderName.Inbox, aqs, iv);
foreach (var item in searchResult.Items)
{
Console.WriteLine(item.Subject);
}
iv.Offset += searchResult.Items.Count;
} while (searchResult.MoreAvailable == true);
I use the following code, to find all messages, which do NOT have set the category "Processed" and which have been received after a given date.
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And,
new SearchFilter.Not(new SearchFilter.IsEqualTo(EmailMessageSchema.Categories, "Processed")),
new SearchFilter.IsGreaterThan(EmailMessageSchema.DateTimeReceived, minDate));
Related
I have the following code:
var search = new TransactionSearchAdvanced();
search.savedSearchId = "680";
SearchResult searchResult = Client.Service.search(search);
var resultList = searchResult.searchRowList;
var castList = resultList.Cast<TransactionSearchRow>();
Everytime I call this method I get 0 search results returned. If I view the saved search in NetSuite itself I have over 1000 results.
I am running a similar search on customers that is 100% working.
public static List<Account> GetCustomerList()
{
var search = new CustomerSearchAdvanced();
search.savedSearchId = "678";
try
{
SearchResult searchResult = Client.Service.search(search);
var resultList = searchResult.searchRowList;
var castList = resultList.Cast<CustomerSearchRow>();
var accountList = new List<Account>();
foreach (var resultRow in castList)
{
var basic = resultRow.basic;
var account = new Account();
account.NsAccountId = basic.entityId?.FirstOrDefault()?.searchValue;
account.Name = basic.companyName?.FirstOrDefault()?.searchValue;
account.EmailAddress1 = basic.email?.FirstOrDefault()?.searchValue;
account.Address = basic.address?.FirstOrDefault()?.searchValue;
account.BillingAddress = basic.billAddress?.FirstOrDefault()?.searchValue;
account.Telephone1 = basic.phone?.FirstOrDefault()?.searchValue;
account.BillingPhone = basic.billPhone?.FirstOrDefault()?.searchValue;
account.Fax = basic.fax?.FirstOrDefault()?.searchValue;
account.WebAddress = basic.url?.FirstOrDefault()?.searchValue;
accountList.Add(account);
}
return accountList;
}
I have tried adding the the role to view transactions. I am totally unfamiliar with netsuite itself and have no idea what it could be since all the settings on my 2 searches are identical.
EDIT
The SearchResult objects are actually different:
looking into this now
In the saved search interface of NetSuite there is a field that needs to be chacked "Run Unrestricted" this is what solved it for me.
is it possible to retrieve only items with a certain flag status by using a SearchFilter?
For example, to retrieve all unread items, the search filter below is used:
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
Is there an equivalent way to retrieve all items that don't have a completed flag assigned?
Thanks
You can do it using the pidTagFlagstatus extended property https://msdn.microsoft.com/en-us/library/office/cc842307.aspx eg if the value is 2 then is flagged if the value is 1 its complete eg
String MailboxToAccess = "user#domain.com";
ExtendedPropertyDefinition PR_FLAG_STATUS = new ExtendedPropertyDefinition(0x1090, MapiPropertyType.Integer);
ExtendedPropertyDefinition FlagRequest = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.Common, 0x8530, MapiPropertyType.String);
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(PR_FLAG_STATUS, 2);
PropertySet fiFindItemPropset = new PropertySet(BasePropertySet.FirstClassProperties);
fiFindItemPropset.Add(FlagRequest);
FolderId FolderToAccess = new FolderId(WellKnownFolderName.Inbox, MailboxToAccess);
ItemView ivItemView = new ItemView(1000);
ivItemView.PropertySet = fiFindItemPropset;
FindItemsResults<Item> FindItemResults = null;
do
{
FindItemResults = service.FindItems(FolderToAccess, sfSearchFilter, ivItemView);
foreach (Item itItem in FindItemResults.Items)
{
Console.WriteLine(itItem.Subject);
Object FlagValue = null;
if (itItem.TryGetProperty(FlagRequest, out FlagValue))
{
Console.WriteLine("Flag : " + FlagValue);
}
}
ivItemView.Offset += FindItemResults.Items.Count;
} while (FindItemResults.MoreAvailable);
I have done the following in the code below but still getting a ServiceObjectPropertyException. I am obviously loading the property as advised here too . Please can anyone help point out what I am doing wrongly
this.ExchangeService = new ExchangeService(ExchangeVersion.Exchange2013);
this.ExchangeService.Credentials = new WebCredentials(mailBox, password);
this.ExchangeService.Url = new Uri("https://mail.xxxxxxxxxxx.com/EWS/Exchange.asmx");
PropertySet itemProperty = new PropertySet();
itemProperty.RequestedBodyType = BodyType.Text;
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
ItemView view = new ItemView(999);
view.PropertySet = itemProperty;
List<ExchangeMailResponse> emails = new List<ExchangeMailResponse>();
FindItemsResults<Item> emailMessage = this.ExchangeService.FindItems(WellKnownFolderName.Inbox, searchFilter, view);
foreach (Item mail in emailMessage)
{
ExchangeMailResponse email = new ExchangeMailResponse();
mail.Load(itemProperty);
email.Message = mail.Body.Text;
}
With the propertyset your trying to use because you haven't used the BasepropertySet overload and you haven't added any properties your only telling exchange to return the IdOnly. So at a basic level you need to at least add the Body property eg
itemProperty.Add(ItemSchema.Body);
However you won't be able to use that propertyset in the FindItems Operations so i would suggest you change your code something like
SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));
PropertySet FindItemPropertySet = new PropertySet(BasePropertySet.IdOnly);
ItemView view = new ItemView(999);
view.PropertySet = FindItemPropertySet;
PropertySet GetItemsPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
GetItemsPropertySet.RequestedBodyType = BodyType.Text;
FindItemsResults<Item> emailMessages = null;
do
{
emailMessages = service.FindItems(WellKnownFolderName.Inbox, searchFilter, view);
if (emailMessages.Items.Count > 0)
{
service.LoadPropertiesForItems(emailMessages.Items, GetItemsPropertySet);
foreach (Item Item in emailMessages.Items)
{
Console.WriteLine(Item.Body.Text);
}
}
} while (emailMessages.MoreAvailable);
Cheers
Glen
I've got the following code:
private void ListCalendarFolders(ref List<EBCalendar> items, int offset)
{
var pageSize = 100;
var view = new FolderView(pageSize, offset, OffsetBasePoint.Beginning);
view.PropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
view.PropertySet.Add(FolderSchema.DisplayName);
view.PropertySet.Add(FolderSchema.EffectiveRights);
view.Traversal = FolderTraversal.Deep;
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot, view);
foreach (Folder myFolder in findFolderResults.Folders)
{
if (myFolder is CalendarFolder)
{
var folder = myFolder as CalendarFolder;
items.Add(EBCalendar.FromEWSFolder(folder));
}
}
if (findFolderResults.MoreAvailable)
{
offset = offset + pageSize;
ListCalendarFolders(ref items, offset);
}
}
Where service is an ExchangeService instance. Unfortunately, it still lists folders that have been deleted, and it doesn't list shared calendars.
How can I get it to list all the shared calendars, and how can I get it to not include the folders that have been deleted?
By Shared Calendars do you mean the calendars under the other calendars node in Outlook ?
If so these Items are NavLinks that are stored in the Common Views folder in a Mailbox which is under the NonIPMSubtree (root) see http://msdn.microsoft.com/en-us/library/ee157359(v=exchg.80).aspx. You can use EWS to get the NavLinks from a Mailbox and use the PidTagWlinkAddressBookEID extended property to get the X500 address of the Mailbox these Links refer to and then use Resolve Name to resolve that to a SMTP Address. Then all you need to do is Bind to that folder eg
static Dictionary<string, Folder> GetSharedCalendarFolders(ExchangeService service, String mbMailboxname)
{
Dictionary<String, Folder> rtList = new System.Collections.Generic.Dictionary<string, Folder>();
FolderId rfRootFolderid = new FolderId(WellKnownFolderName.Root, mbMailboxname);
FolderView fvFolderView = new FolderView(1000);
SearchFilter sfSearchFilter = new SearchFilter.IsEqualTo(FolderSchema.DisplayName, "Common Views");
FindFoldersResults ffoldres = service.FindFolders(rfRootFolderid, sfSearchFilter, fvFolderView);
if (ffoldres.Folders.Count == 1)
{
PropertySet psPropset = new PropertySet(BasePropertySet.FirstClassProperties);
ExtendedPropertyDefinition PidTagWlinkAddressBookEID = new ExtendedPropertyDefinition(0x6854, MapiPropertyType.Binary);
ExtendedPropertyDefinition PidTagWlinkGroupName = new ExtendedPropertyDefinition(0x6851, MapiPropertyType.String);
psPropset.Add(PidTagWlinkAddressBookEID);
ItemView iv = new ItemView(1000);
iv.PropertySet = psPropset;
iv.Traversal = ItemTraversal.Associated;
SearchFilter cntSearch = new SearchFilter.IsEqualTo(PidTagWlinkGroupName, "Other Calendars");
// Can also find this using PidTagWlinkType = wblSharedFolder
FindItemsResults<Item> fiResults = ffoldres.Folders[0].FindItems(cntSearch, iv);
foreach (Item itItem in fiResults.Items)
{
try
{
object GroupName = null;
object WlinkAddressBookEID = null;
// This property will only be there in Outlook 2010 and beyond
//https://msdn.microsoft.com/en-us/library/ee220131(v=exchg.80).aspx#Appendix_A_30
if (itItem.TryGetProperty(PidTagWlinkAddressBookEID, out WlinkAddressBookEID))
{
byte[] ssStoreID = (byte[])WlinkAddressBookEID;
int leLegDnStart = 0;
// Can also extract the DN by getting the 28th(or 30th?) byte to the second to last byte
//https://msdn.microsoft.com/en-us/library/ee237564(v=exchg.80).aspx
//https://msdn.microsoft.com/en-us/library/hh354838(v=exchg.80).aspx
String lnLegDN = "";
for (int ssArraynum = (ssStoreID.Length - 2); ssArraynum != 0; ssArraynum--)
{
if (ssStoreID[ssArraynum] == 0)
{
leLegDnStart = ssArraynum;
lnLegDN = System.Text.ASCIIEncoding.ASCII.GetString(ssStoreID, leLegDnStart + 1, (ssStoreID.Length - (leLegDnStart + 2)));
ssArraynum = 1;
}
}
NameResolutionCollection ncCol = service.ResolveName(lnLegDN, ResolveNameSearchLocation.DirectoryOnly, false);
if (ncCol.Count > 0)
{
FolderId SharedCalendarId = new FolderId(WellKnownFolderName.Calendar, ncCol[0].Mailbox.Address);
Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
rtList.Add(ncCol[0].Mailbox.Address, SharedCalendaFolder);
}
}
}
catch (Exception exception)
{
Console.WriteLine(exception.Message);
}
}
}
return rtList;
}
Cheers
Glen
You need to specify a searchfilter.
this is described here, though im not sure which Schema is the correct one, my guess would be Archieved.
So you would do something like this:
SearchFilter searchFilter = new SearchFilter.IsEqualTo(FolderSchema.Archieved, false);
FindFoldersResults findFolderResults = service.FindFolders(WellKnownFolderName.MsgFolderRoot,searchFilter, view);
Glen post is perfect but binding folder gives error. However i solved this. Instead of this line:
Folder SharedCalendaFolder = Folder.Bind(service, SharedCalendarId);
use the following line for shared folder binding
CalendarFolder calendar = CalendarFolder.Bind(service, new FolderId(WellKnownFolderName.Calendar, OwnerEmailAddress), new PropertySet());
Here OwnerEmailAddress is Email Address of Owner or you can write ncCol[0].Mailbox.Address if using Glen's code.
I'm interfacing with MailChimp using MCAPI.NET and I need to specify the groupings for subscriptions.
string emailAddr = "somebody#somewhere.net";
MailChimp.MCApi mc = new MailChimp.MCApi("myapikey", true);
var merges = new MailChimp.Types.List.Merges();
merges.Add("FNAME", "MyFirstName");
merges.Add("LNAME", "MyLastName");
var group = new string[]{"PSS"};
var grp = new MailChimp.Types.List.Grouping("Staff Type", group);
merges.Add("Groupings", grp);
mc.ListSubscribe("mylistid", emailAddr, merges);
My grouping isn't getting set. Does someone have a working example they could share?
The problem with your code is that you are not adding a list of groupings to the merge var "Groupings". The value has to be of the following type:
MailChimp.Types.MCList<MailChimp.Types.List.Grouping>
Here is a working copy:
var merges = new List.Merges();
var groupingList = new MailChimp.Types.MCList<MailChimp.Types.List.Grouping>();
var grouping = new MailChimp.Types.List.Grouping(myGroupId, new string[] { group1, group2 });
groupingList.Add(grouping);
merges["Groupings"] = groupingList;
// You may find it practical to include the following options, at least while testing the groupings
var options = new MailChimp.Types.List.SubscribeOptions();
options.DoubleOptIn = false;
options.ReplaceInterests = false;
options.SendWelcome = false;
mcapi.ListSubscribe(myMailChimpListId, email, merges, options);