Enrolling Anonymous Users in Engagement Plans - sitecore

I know that it is possible to enroll users in an engagement plan from with Sitecore by adding them to a specific state in the plan when they visit a campaign URL, adding them when they submit a Web Forms for Marketers Form, and manually adding them in the Supervisor interface.
Additionally, I know that you can use the API to add a user as described here:
http://briancaos.wordpress.com/2013/06/03/programming-for-sitecore-dms-engagement-plans/
However, that method requires a username.
I would like to enroll anonymous users in an engagement plan when they visit any page represented by a particular template in Sitecore (ie, page from the Product template). Is this possible using the API?

To expand on my above comment, and to supplement your own answer, here's a processor that you could add to the after the ItemResolver in the httpRequestBegin pipeline that would achieve the desired result. It is a very basic version that you could embellish as you see fit
class CampaignRedirect
{
public void Process(HttpRequestArgs args)
{
var request = HttpContext.Current.Request;
// must not already have the querystring in the URL
if(request.QueryString["sc_camp"] != null &&
request.QueryString["sc_camp"] != "XXXXXXXX")
return;
// must have a context item
if(Sitecore.Context.Item == null)
return;
var item = Sitecore.Context.Item;
// must be the right template
if(item.TemplateID.ToString() != "{XXXXXXXXX-XXXX-XXXXXX}")
return;
var basicUrl = LinkManager.GetItemUrl(item);
var response = HttpContext.Current.Response;
response.Redirect(basicUrl + "?sc_camp=XXXXXXX");
}
}
If you're not familiar with adding processors, take a look here.

Per Sitecore support, this is not currently possible. However, I was able to achieve what I wanted by adding a jQuery AJAX call to the campaign URL to the sublayout used by the page type in question. Naturally this only works for clients with JS enabled, but for my purposes, that is not an issue.
<script type="text/javascript">$(function() { $.get('/?sc_camp=[campaignid]'); });</script>
Edited 2014-05-19
I found a way to do this via the Sitecore API. This is rough and needs to check for null values, exceptions, etc., but it does work:
string cookieVal = Request.Cookies["SC_ANALYTICS_GLOBAL_COOKIE"].Value;
List<Guid> guids = new List<Guid>() {
new Guid(cookieVal)
};
Guid automationStateId = new Guid("{24963AE9-1C8C-4E18-8EEE-01BC249D1F1B}");
Guid automationId = Sitecore.Context.Database.GetItem(new Sitecore.Data.ID(automationStateId)).ParentID.ToGuid();
Sitecore.Analytics.Automation.Data.AutomationManager.Provider.CreateAutomationStatesFromBulk(guids, automationId, automationStateId);

Related

Implementing SEO friendly URLs in Sitecore-uCommerce

I am implementing a default Sitecore-uCommerce SEO friendly URLs mechanics and I run into issues.
I looked into ItemResolver processor of uCommerce and I still do not understand how uCommerce sets the Sitecore Context Item. It seems like it uses an uCommerce Item's Guid for Sitecore.Context.Item. Somehow it is not the case, but I do not see the real Sitecore Item to be set as Context item. And uCommerce items do not have the layout details on them. Or am I wrong?
private ID FindSitecoreIdForProduct(int productId)
{
IRepository<Product> repository = ObjectFactory.Instance.Resolve<IRepository<Product>>();
Product product = repository.Get(productId);
if (product != null)
{
return new ID(product.Guid);
}
return ID.Null;
}
Then it makes
ID iD = this.FindSitecoreIdForProduct(productId);
if (iD == ID.Null)
{
return;
}
Context.Item = Context.Database.GetItem(iD);
I would like it to be a specific Sitecore Item with a rendering showing the product details. The URLs are of type
http://sitename.com/productdetailpage/productname/c-25/p-125
If you could just explain me how uCommerce gets to the real Sitecore Item and sets it as a Context.Item, I guess it will be enough for me.
You are on the right way.
They move the context item to other item. I didn't like how they deal with url, and I need other ProductResolver.
Ucommerce have products in his own db, and they created a dataProvider to bring products into Sitecore.
The Ucommerce products are located in Sitecore under /sitecore/uCommerce/Products .
The shops,category and subcategory are located under /sitecore/uCommerce/Store.
Please check this link to have a clean idea how ucommerce is dealing with url:
http://docs.ucommerce.net/ucommerce/v7.0/sitecore/working-with-nice-urls-in-sitecore.html
I also have the same issue like you and I created a custom ItemResolver.
I defined processor in this way on httpRequestBegin pipeline.
<processor type="NameSpace.ProductResolver, Assembly" patch:instead="processor[#type='UCommerce.Sitecore.Pipelines.ItemResolver, UCommerce.Sitecore']"/>
I created in Sitecore a new template name ProductPage, I create a new item named Product of type ProductPage
My requirements was to have url like : /Shoes/Running/NIKEAIRZOOMPEGASUS33
When you browse to /category/subcategory/productid my productResolver is triggered.
I check if category,subcategory and product exist.
If they exist I set the current category and current product.
SiteContext.Current.CatalogContext.CurrentProduct=current_product;
//you need to check if product is in current category
I set my Context Item to be the Product item
var pathList = args.LocalPath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries).ToList();
var currentProduct= GetCurrentProduct(pathList);
// in above function I am getting the current product, checking if is correct category and subcategory
if (currentProduct != null)
{
SiteContext.Current.CatalogContext.CurrentProduct = currentProduct;
Sitecore.Context.Item = productItem;
}

Sitecore ECM 2.1: Is there a way to segment the users based on a condition?

Is there any way to send mails to certain users based on a condition in ECM 2.1 . For example, I want to send mails to only those users whose user profile property Country='USA'. Is there a way to do this in ECM 2.1?
Earlier for ECM 1.3 we used to use a third party segmentation module below
https://marketplace.sitecore.net/en/Modules/Sitecore_EmailCampaign_Segment.aspx
But it does not support ECM 2.1. So I was wondering how to implement it in ECM 2.1 . By the way we are using Sitecore 7.2
If you don't mind extending ECM slightly you could tap into the DispatchNewsletter Pipline.
If you add processor like the following, you could get all the users dynamically and add them to the subscribers list. You just need to make sure that this only fires on certain scenarios to avoid this interfering with the core product functionality.
public class GetUSASubscribers
{
public void Process(DispatchNewsletterArgs args)
{
if(CanProcessEmail(args))
{
var matches = UserManager.GetUsers().Where(usr => usr.Profile["Country"].Equals("USA")).ToList();
foreach (var username in matches)
{
if (User.Exists(username.Name))
{
var contact = Contact.FromName(username.LocalName);
args.Message.Subscribers.Add(contact);
args.Message.SubscribersNames.Add(contact.Name);
}
}
}
}
}
You can register the processor as follows in your Sitecore.EmailCampaign.config
<DispatchNewsletter>
<processor type="Sitecore.Modules.EmailCampaign.Core.Pipelines.DispatchNewsletter.CheckPreconditions, Sitecore.EmailCampaign" />
<processor type="YourClass, YourNamespace" />
........................
</DispatchNewsletter>
To make it more dynamic you could add a Rules engine field to each message item to determine which users are added to the subscriber list. So the logic e.g where user profile["country"] equals 'USA' could be in the rules field.
For reference, some more detail on the set up of rules in Sitecore.
http://blog.horizontalintegration.com/2013/12/06/bending-the-sitecore-rules-field-to-your-will-with-sitecore-7-1-part-1/

Accessing Item Fields via Sitecore Web Service

I am creating items on the fly via Sitecore Web Service. So far I can create the items from this function:
AddFromTemplate
And I also tried this link: http://blog.hansmelis.be/2012/05/29/sitecore-web-service-pitfalls/
But I am finding it hard to access the fields. So far here is my code:
public void CreateItemInSitecore(string getDayGuid, Oracle.DataAccess.Client.OracleDataReader reader)
{
if (getDayGuid != null)
{
var sitecoreService = new EverBankCMS.VisualSitecoreService();
var addItem = sitecoreService.AddFromTemplate(getDayGuid, templateIdRTT, "Testing", database, myCred);
var getChildren = sitecoreService.GetChildren(getDayGuid, database, myCred);
for (int i = 0; i < getChildren.ChildNodes.Count; i++)
{
if (getChildren.ChildNodes[i].InnerText.ToString() == "Testing")
{
var getItem = sitecoreService.GetItemFields(getChildren.ChildNodes[i].Attributes[0].Value, "en", "1", true, database, myCred);
string p = getChildren.ChildNodes[i].Attributes[0].Value;
}
}
}
}
So as you can see I am creating an Item and I want to access the Fields for that item.
I thought that GetItemFields will give me some value, but finding it hard to get it. Any clue?
My advice would be to not use the VSS (Visual Sitecore Service), but write your own service specifically for the thing you want it to do.
This way is usually more efficient because you can do exactly the thing you want, directly inside the service, instead of making a lot of calls to the VSS and handle your logic on the clientside.
For me, this has always been a better solution than using the VSS.
I am assuming you are looking to find out what the fields looks like and what the field IDs are.
You can call GetXml with the ID, it returns the item and all the versions and fields set in it, it won't show fields you haven't set.

Sitecore poll module sample code

I installed and configured the Poll Module to work fine. The website I am working on will have a Poll instance on a page either as a left rail or a right rail item. The Polls would be setup in a separate folder. On the page item there will be a multilist field which will point to the Polls folder and the user can select whichever poll they choose to. The folder will also contain different sublayouts which will could be selected to be displayed on the rail. I have some custom code which will look at the above mentioned multilist field and show these rail items.
I don't know how to display a Poll programmatically. I haven't found any code samples and also not sure where to set the sublayout. Should I set it on the Poll template itself and then let use code to display it? How can I achieve this in code? Any code samples would be helpful.
Hoping that you will this time accept the answer, I wrote the following for you (based on the OMS Poll module:
Read out the field on your item:
Sitecore.Data.Fields.ReferenceField selectedPoll = (Sitecore.Data.Fields.ReferenceField)Sitecore.Context.Item.Fields["Poll"];
Get the pollItem:
if (selectedPoll.TargetItem != null)
{
Item pollItem = selectedPoll.TargetItem;
if (pollItem != null)
{
Check if the poll is opened or closed and place:
Sitecore.Data.Fields.CheckboxField pollClosed = (Sitecore.Data.Fields.CheckboxField)pollItem.Fields["Closed"];
if (pollClosed.Checked == false)
{
// Set the header of the snippetBlock
ltPollHeader.Text = pollItem.Name;
PollVotingSublayout pollSublayout = (PollVotingSublayout)LoadControl("/sitecore modules/Shell/Poll Module/Controls/PollVotingSublayout.ascx");
pollSublayout.Attributes.Add("sc_parameters", "PollPath=" + pollItem.Paths.FullPath);
pollSublayout.CurrentPoll = (PollItem)pollItem;
this.pollRegion.Controls.Add(pollSublayout);
phPollSnippet.Visible = true;
int blockPos = 0;
if (snippetField != null)
{
if (snippetField.GetItems().Any())
{
blockPos = 1;
}
}
string cssClass = String.Empty;
if (blockPos == 0)
{
cssClass = "snippetColHomeFirst";
}
this.SetClass("snippetColHome", cssClass);
}
Hope that you can make up something using this snippets. Good luck!
There should be a user account called "poll" on the sitecore domain. This account is normally used internal by the poll. In the comment of this account is stated: "Please do not remove this account". the account should have the Sitecore Minimal Page Editor role. I don't know the poll user credentials, but you might find that by either using reflector or opening cs files that you can get by downloading the source.

Can't access a new field programmatically on a template in Sitecore

my question is basically the same as #Bob Black's Cannot access sitecore item field via API but I agree with #techphoria414 that the accepted solution is not necessary and in my case does not work.
In my own words, I have a template Departure that I have been using for about a year now creating and updating items programmatically. I have added a new field Ship to the template. When I create a new item the field comes up as null when I try to access it using departure.Fields["Ship"]. If I step over the line causing the exception then after calling departure.Editing.EndEdit() I can then see the Ship field if I call departure.Fields.ToList(). If I add the template to a content item via the Sitecore GUI I can see the field and use it, and if I look at a content item which is based on the template I can see the new field too. So it is only when I access the template/item programmatically that it is null.
I have sitecore running on my local machine with a local sqlserver, and publish to my local machine.
Here is my code
String ship = "MSDisaster";
foreach (Language language in SiteLanguages)
{
departure = departure.Database.GetItem(departure.ID, language);
departure.Editing.BeginEdit();
try
{
departure.Fields["StartDate"].Value = GetSitecoreDateString(xDep, "StartDate");
departure.Fields["EndDate"].Value = GetSitecoreDateString(xDep, "EndDate");
departure.Fields["Guaranteed"].Value = xDep.SelectSingleNode("./Guaranteed").InnerText;
departure.Fields["Status"].Value = xDep.SelectSingleNode("./Status").InnerText;
departure.Fields["Currency"].Value = ConvertLanguageToCurrency(language);
departure.Fields["Market"].Value = ConvertLanguageToMarket(language);
departure.Fields["TwinSharePrice"].Value = GetPrice(xDep, "twn", language);
departure.Fields["SinglePrice"].Value = GetPrice(xDep, "sgl", language);
if (!String.IsNullOrEmpty(ship))
departures.Fields["Ship"].Value = ship;
}
catch (Exception ex)
{
departure.Editing.CancelEdit();
log.Error(ex);
throw ex;
}
departure.Editing.EndEdit();
}
So, how do I get the field be picked up?
Thanks,
James.
Firstly do you see the field in the web database in the sitecore administration.
If you do the item has the fields, you then should check the template assigned on the item and double check that the field is actually called "ship" and check the case as ive seen this as an issue before.
Also check the security on the item and field just in case anyone changed anything.
Next try and get the data from the item but instead of using the field name, use the field ID.
Let me know how you go?
Chris
Sorry Chris, StackOverflow, and the others who looked at my questions. It was a stupid typo. It's even there in my question
departure.Fields["SinglePrice"].Value = GetPrice(xDep, "sgl", language);
if (!String.IsNullOrEmpty(ship))
departures.Fields["Ship"].Value = ship;
}
departure is the item I am working on, departures is the collection it belongs to... doh.
So what is the protocol here? Do I delete my question now because it isn't really going to help anyone code better?
James.