Sitecore 8 EXM add a contact to list from listmanager - sitecore

I'm using Sitecore 8 and the new Email Experience Manager module.
I have configured a newsletter email message with an empty list from the listmanager as recipients.
When subscribing for the newsletter via a selfmade form, I receive an email address and a name.
Now I want to make a new contact with this mail and name and add it to the list in my listmanager via code.
Is there any way to call this list via the api and add a contact to it?

To create a contact, you can use the sample code below, the contact name is usually the domain name plus the username, e.g. domain\username.
public static Contact CreateContact([NotNull] string contactName, [NotNull] string contactEmail, [NotNull] string contactLanguage)
{
Assert.ArgumentNotNullOrEmpty(contactName, "contactName");
Assert.ArgumentNotNullOrEmpty(contactEmail, "contactEmail");
Assert.ArgumentNotNullOrEmpty(contactLanguage, "contactLanguage");
var contactRepository = new ContactRepository();
var contact = contactRepository.LoadContactReadOnly(contactName);
if (contact != null)
{
return contact;
}
contact = contactRepository.CreateContact(ID.NewID);
contact.Identifiers.AuthenticationLevel = AuthenticationLevel.None;
contact.System.Classification = 0;
contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
contact.Identifiers.Identifier = contactName;
contact.System.OverrideClassification = 0;
contact.System.Value = 0;
contact.System.VisitCount = 0;
var contactPreferences = contact.GetFacet<IContactPreferences>("Preferences");
contactPreferences.Language = contactLanguage;
var contactEmailAddresses = contact.GetFacet<IContactEmailAddresses>("Emails");
contactEmailAddresses.Entries.Create("test").SmtpAddress = contactEmail;
contactEmailAddresses.Preferred = "test";
var contactPersonalInfo = contact.GetFacet<IContactPersonalInfo>("Personal");
contactPersonalInfo.FirstName = contactName;
contactPersonalInfo.Surname = "recipient";
contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
return contact;
}
After creating the contact, use the following sample code to add the contact to a recipient list.
var repository = new ListManagerCollectionRepository();
var recipientList = repository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
var xdbContact = new XdbContactId(contactId);
if (!recipientList.Contains(xdbContact, true).Value)
{
recipientList.AddRecipient(xdbContact);
}
}

Essentially you can follow this example
<%# Page Language="c#" %>
<%# Import Namespace="Sitecore.Analytics" %>
<%# Import Namespace="Testing.ContactFacets.Model" %>
<!DOCTYPE html>
<html>
<head>
<title>Add Employee Data</title>
</head>
<body>
<%
var contact = Tracker.Current.Contact;
var data = contact.GetFacet<IEmployeeData>("Employee Data");
data.EmployeeId = "ABC123";
%>
<p>Employee data contact facet updated.</p>
<p>Contact ID: <b><%=contact.ContactId.ToString()%></b></p>
<p>Employee #: <b><%=data.EmployeeId%></b></p>
</body>
</html>
The changes are then written when the session is abandoned, like so
<%# Page language="c#" %>
<script runat="server">
void Page_Load(object sender, System.EventArgs e) {
Session.Abandon();
}
</script>
<!DOCTYPE html>
<html>
<head>
<title>Session Abandon</title>
</head>
<body>
</body>
</html>
Follow this link for the source and more information - http://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2014/09/introducing-contact-facets

I have had the exact same issue, i.e. the list manager reports 0 contacts after adding the contact to the recipient list.
I have investigated the issue closer and found that adding a contact to a recipient list actually just sets a field on the contact in the "sitecore_analytics_index" index (assuming you use Mongo/XDB as the underlying storage). Specifically, Sitecore should update the "contact.tags" field on the contact document with the value "ContactLists:{recipientListGuid}". I tried opening the index with Luke to verify that this field was indeed not being set in the index. The index is located in C:\inetpub\wwwroot[Sitename]\Data\indexes\sitecore_analytics_index.
This led me to the conclusion, that you have to save the contact after adding him to the recipient list.
Summing up, the following code works for me:
var ecm = EcmFactory.GetDefaultFactory();
XdbContactId contactId = /* some valid contact id */;
LeaseOwner leaseOwner = new LeaseOwner("UpdateContact-" + Guid.NewGuid().ToString(), LeaseOwnerType.OutOfRequestWorker);
Sitecore.Analytics.Tracking.Contact contact;
string webClusterName;
var status = ecm.Gateways.AnalyticsGateway.TryGetContactForUpdate(contactId.Value,
leaseOwner,
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(5),
out contact, out webClusterName);
var recipientList = ecm.Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
if (!recipientList.Contains(contactId, true).Value)
{
recipientList.AddRecipient(contactId);
}
}
contact.ContactSaveMode = ContactSaveMode.AlwaysSave;
var contactRepository = new ContactRepository();
var success = contactRepository.SaveContact(contact, new ContactSaveOptions(true, leaseOwner));
Note, the above code is used in an update-scenario. In your case, I guess you just have to move this code:
contactRepository.SaveContact(contact, new ContactSaveOptions(true, null));
After this:
var recipientList = EcmFactory.GetDefaultFactory().Bl.RecipientCollectionRepository.GetEditableRecipientCollection(recipientListId);
if (recipientList != null)
{
var xdbContact = new XdbContactId(contactId);
if (!recipientList.Contains(xdbContact, true).Value)
{
recipientList.AddRecipient(xdbContact);
}
}
UPDATE: Actually the above only works if the contact saved is the contact currently tracked by Sitecore Analytics.

in case you have a tracker available and you dont need the update immediately, the following should work (note that the contact is added to the list upon session expiration):
//private const string ContactListTagName = "ContactLists";
var contact = Tracker.Current.Contact;
// Identify
if (contact.Identifiers.IdentificationLevel < ContactIdentificationLevel.Known)
{
Tracker.Current.Session.Identify(email);
}
// Set Email
var contactEmail = contact.GetFacet<IContactEmailAddresses>("Emails");
// Create an email address if not already present
// This can be named anything, but must be the same as "Preferred" if you want
// this email to show in the Experience Profiles backend.
if (!contactEmail.Entries.Contains("Preferred"))
contactEmail.Entries.Create("Preferred");
// set the email
var emailEntry = contactEmail.Entries["Preferred"];
emailEntry.SmtpAddress = email;
contactEmail.Preferred = "Preferred";
// set FirstName and Surname (required for List Manager, "N/A" might not be ideal but I don't know how Sitecore behaves with empty strings)
var personal = contact.GetFacet<IContactPersonalInfo>("Personal");
personal.FirstName = personal.FirstName ?? "N/A";
personal.Surname = personal.Surname ?? "N/A";
// Add preferred language
var preferences = contact.GetFacet<IContactPreferences>("Preferences");
preferences.Language = Context.Language.Name;
// Here is the actual adding to the list by adding tags
using (new SecurityDisabler())
{
var id = ID.Parse("CONTACTLISTID");
contact.Tags.Set(ContactListTagName, id.ToString().ToUpperInvariant());
}
Greetz,
Markus

Related

Simultaneous emails sent to different addresses based on form input

What I have:
A google form with checkbox options so the user can choose ALL that
apply (6 total options)
For each option, there is a specific email associated with each option (6 different emails)
What is occurring:
When a single option is chosen, the email goes out to the correct person
When multiple options are chosen, an email goes out only to the first option
The spreadsheet collects the data correctly, showing all the options chosen, but only one email actually goes out
What I need:
Multiple emails sent to the different specified addresses if their option is one of the selected ones
Current Script:
function sendFormByEmail(e)
{
console.log(JSON.stringify(e))
// Remember to replace XYZ with your own email address
var named_values = e.namedValues
var teachername = named_values["Teacher Name"];
var info = named_values["Your message/announcement"];
var time = named_values["Please include time frame"];
var photos = named_values["Include photos with this form if applicable; you can also create the graphic for social media and include below"];
var announce = e.values[3];
var address = [];
if(announce.match('School Intercom Announcement')){
var address = "mhhsmedia#yanceync.net";
var subject = "School Announcement Request";
}
if(announce.match('MHHS Website')){
var address = "heritagecougars#yanceync.net";
var subject = "Website posting request";
}
if(announce.match('MHHS Social Media')) {
var address = "socialmedia#yanceync.net";
var subject = "Social Media Request";
}
if(announce.match('Week in Pics')) {
var address = "ycspics#yanceync.net";
var subject= "Week in Pics Request";
}
if(announce.match('Remind text message')){
var address = "jstipton#yanceync.net";
var subject = "Remind message request";
}
if(announce.match('Phone call home')){
var address = "blackboardcall#yanceync.net";
var subject = "All-Call Request";
}
// The variable e holds all the form values in an array.
// Loop through the array and append values to the body. ;
var email = address
var message = "";
for(var field in e.namedValues)
message += field + ' :: '
+ e.namedValues[field].toString() + "\n\n";
MailApp.sendEmail(email, subject, message);
}
Things I have tried with no luck:
I attempted to join the addresses with:
var email = address.join(",")
This gave me a script failure that address.join was not a function
I tried including under each if statement:
var email = "jstipton#yanceync.net";
var subject = "All-Call Request";
MailApp.sendEmail(email, subject, message);
This resulted in still only one email being sent to the first option chosen, regardless of how many were chosen after it.
Thank you in advance for your willingness to assist me!
If you have included,under each if statement, theMailApp.sendEmail code and only 1 email is send, that's because your are entering in only one condition.
But why announce match only 1 condition ? I believe there is only one value announce='Week in Pics' (or equivalent) passed into the sendFormByEmail(e) function.
So be sure that announce have a value like "School Intercom Announcement MHHS Website "
Just for you information, there is a lot to say about your code :
The way value is affected into address field (several var address) is not so good. You used array, that's a perfect start, but to add data into an array, it's the push method :
// 🔴 what you use
var address = []; // address = [] an array
var address = "mhhsmedia#yanceync.net"; // address = "mhhsmedia#yanceync.net" a string
var address = "heritagecougars#yanceync.net"; // address = "heritagecougars#yanceync.net" a string
// 🟢 what work
var address = []; // address = [] an array
address.push("mhhsmedia#yanceync.net"); // address = ["mhhsmedia#yanceync.net"] an array of string
address.push("heritagecougars#yanceync.net"); // address = ["mhhsmedia#yanceync.net","heritagecougars#yanceync.net"] an array of string
// So your code can look like as bellow
// ...
var address = [];
if(announce.match('School Intercom Announcement')){
address.push("mhhsmedia#yanceync.net");
subject.push("School Announcement Request");
}
if(announce.match('MHHS Website')){
address.push("heritagecougars#yanceync.net");
subject.push("Website posting request");
}
// ...
for (var email in address){
var subjectToSend = subject.pop()
//...
}
As improvement, you can use switch switch statement, that is far more easier to read than several if.
Finally, match is for regex, if you never heard of such thing have a look, it's a life changer.

Changing image based on location data output

I am trying to show/echo users location on a webpage using maxmind geoip2 paid plan, I also want to show different images based on the state/city names output.
For example, if my webpage shows the user is from New York, I would like to show a simple picture of New York, if the script detects the user is from Washington, the image should load for Washington.
This is the snippet I have tried but doesn't work.
<script type="text/javascript">
if
$('span#region=("New York")') {
// Display your image for New York
document.write("<img src='./images/NY.jpg'>");
}
else {
document.write("<img src='./images/different.jpg'>");
}
</script>
This is the code in the header.
<script src="https://js.maxmind.com/js/apis/geoip2/v2.1/geoip2.js" type="text/javascript"></script>
<script>
var onSuccess = function(geoipResponse) {
var cityElement = document.getElementById('city');
if (cityElement) {
cityElement.textContent = geoipResponse.city.names.en || 'Unknown city';
}
var countryElement = document.getElementById('country');
if (countryElement) {
countryElement.textContent = geoipResponse.country.names.en || 'Unknown country';
}
var regionElement = document.getElementById('region');
if (regionElement) {
regionElement.textContent = geoipResponse.most_specific_subdivision.names.en || 'Unknown region';
}
};
var onError = function(error) {
window.console.log("something went wrong: " + error.error)
};
var onLoad = function() {
geoip2.city(onSuccess, onError);
};
// Run the lookup when the document is loaded and parsed. You could
// also use something like $(document).ready(onLoad) if you use jQuery.
document.addEventListener('DOMContentLoaded', onLoad);
</script>
And this simple span shows the state name in body text of the Html when the page loads.
<span id="region"></span>
now the only issue is the image doesn't change based on users location, what am i doing wrong here?
Your example is missing some code, but it looks like you are running some code immediately and some code in a callback, a better way to do it is to have all the code in the callback:
// whitelist of valid image names
var validImages = ["NJ", "NY"];
// get the main image you want to replace
var mainImage = document.getElementById('mainImage');
if (mainImage) {
// ensure there is a subdivision detected, or load the default
if(geoipResponse.subdivisions[0].iso_code && validImages.includes( && geoipResponse.subdivisions[0].iso_code)){
mainImage.src = "./images/" + geoipResponse.subdivisions[0].iso_code + ".jpg";
} else {
mainImage.src = "./images/different.jpg";
}
}
Then just have the image you want to replace be:
<img src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D" id="mainImage" />
Notes:
If you are using a responsive image, make sure your transparent gif is the same ratio height of to width as your final image to avoid page reflows.
You will have to load the different.jpg in the onError callback as well.

Django has no response to anchor tag

test
...
<div class="tab-pane " id="test">
<table>
...
</table>
</div>
When #test anchor is clicked, the behavior should be logged in the server. So in urls.py, I defined something like this
url(r'#test$', views.log())
or
url(r'.*#test$', views.log())
But it seems it doesn't work.
I have to use anchor here, because I don't want to refresh the page.
Any ideas?
Here is some JavaScript that takes links with a href attribute starting with # and makes a request to https://localhost:8000/<whatever was after the hash sign> whenever the links are clicked. It's not robust and it needs to be modified for your circumstances, but maybe it works as a starting point.
var hashLinks = document.querySelectorAll('a[href^="#"]');
var i;
function hashLinkClicked(event) {
var hash, url, request;
// You probably want to allow default link behaviour here
event.preventDefault();
hash = this.hash;
// Cut hash character out of URL
url = 'http:/localhost:8000/' + hash.slice(1);
request = new XMLHttpRequest();
request.onreadystatechange = function () { /* Handle response here */ };
request.open('GET', url);
request.send();
}
for (i = 0; i < hashLinks.length; i++) {
hashLinks[i].addEventListener('click', hashLinkClicked);
}

Get Rendered HTML From Sitecore Item

I need to get the rendered HTML output from a given Sitecore item, assuming it has a layout. I need it to be the latest version of the rendered content whether it's published or not. Using a web request approach like WebClient or HtmlAgility pack will not work because they make the request as an anonymous user which will only render the latest published version (and I need the latest version no matter the state.) Any thoughts? I have everything working I just cant find a way to impersonate or elevate the rights while I execute the page requests.
You could go the WebClient or HtmlAgility pack, but silently login the user based on a token in the query string:
public static class UserExtensions
{
public const string TokenKey = "UserToken";
public const string TokenDateKey = "UserTokenDate";
public static ID CreateUserToken(this User user)
{
if (user.IsAuthenticated)
{
var token = ID.NewID;
user.Profile.SetCustomProperty(TokenKey, token.ToString());
user.Profile.SetCustomProperty(TokenDateKey, DateTime.Now.ToString());
user.Profile.Save();
return token;
}
else
return ID.Null;
}
public static bool IsTokenValid(this User user, string token, TimeSpan maxAge)
{
var tokenId = ID.Null;
if (ID.TryParse(token, out tokenId))
{
var minDate = DateTime.Now.Add(-maxAge);
var tokenDateString = user.Profile.GetCustomProperty(TokenDateKey);
var tokenDate = DateTime.MinValue;
DateTime.TryParse(tokenDateString, out tokenDate);
if (tokenDate < minDate)
return false;
var storedToken = user.Profile.GetCustomProperty(TokenKey);
var storedTokenId = ID.NewID;
if (ID.TryParse(storedToken, out storedTokenId))
return storedTokenId == tokenId;
}
return false;
}
}
Then patch in a HttpRequestProcessor to look for the token:
public class SilentUserLogin : HttpRequestProcessor
{
public TimeSpan MaximumAge
{
get;
set;
}
public override void Process(HttpRequestArgs args)
{
var userValue = args.Context.Request.QueryString["user"];
var tokenValue = args.Context.Request.QueryString["token"];
if (!string.IsNullOrEmpty(userValue) && !string.IsNullOrEmpty(tokenValue))
{
// find user
var user = User.FromName(userValue, AccountType.User);
if (user != null)
{
// Check token is valid
if ((user as User).IsTokenValid(tokenValue, MaximumAge))
{
// log user in
AuthenticationManager.Login(user as User);
}
else
Log.Audit("User token has expired for user: '{0}'".FormatWith(user.Name), this);
}
else
Log.Audit("Failed to locate auto login user " + userValue, this);
}
}
Patch this in with a config file:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor type="Namespace.SilentUserLogin,Assembly" patch:after="*[#type='Sitecore.Pipelines.HttpRequest.StartMeasurements, Sitecore.Kernel']">
<MaximumAge>00:02:00</MaximumAge>
</processor>
</httpRequestBegin>
</pipelines>
</sitecore>
</configuration>
Finally, call the page via WebClient or HtmlAgility:
var token = Sitecore.Context.User.CreateUserToken();
var url = new UrlString();
url.HostName = HttpContext.Current.Request.Url.Host;
url.Protocol = HttpContext.Current.Request.IsSecureConnection ? "https" : "http";
url.Path = "/";
url["sc_itemid"] = myItem.ID.ToString();
url["sc_lang"] = myItem.Language.ToString();
// Add parameters to allow accessing the master DB
url["user"] = Sitecore.Context.User.Name;
url["token"] = token.ToString();
// Call the url here
This code was cribbed from a similar situation where I needed a URL to feed to a PDF generation library, which behind the scenes fired up IE and hit the site as an anonymous user. This way we could pass a limited time security token via the query string.
You can setup a "preview" site that shows content from the master database as opposed to the public-facing published content. This article will help setting that up: How to Setup a Sitecore Preview Site to Review Content Before Publishing
Once you have this setup on a unique URL, you can then make a WebRequest to pages or use HtmlAgilityPack.

How to embed latest tweets in Sitecore 6.5

I have to embed latest tweets in a Sitecore 6.5 project as given below image
How can I implement this functionality.
Thanks
Hello You can do this See below code. I am pasting code here for a single sublayout. Please update some tokens as per your requirement. This code will return you a Json you can get that json in JQuery.
Code - ----------------
public partial class LatestTweets : BaseSublayout
{
SiteItem objSiteItem = SiteItem.GetSiteRoot();
protected void Page_Load(object sender, EventArgs e)
{
if (objSiteItem != null)
{
hdJsonData.Value = GetTweets();
frLatestTweets.Item = objSiteItem;
frLatestTweets.Item = objSiteItem;
frFollowUsLink.Item = objSiteItem;
ltFollowUs.Text = Sitecore.Globalization.Translate.Text(Constants.FOLLOW_US);
ltTweetUs.Text = Sitecore.Globalization.Translate.Text(Constants.TWEET_US);
}
}
public string GetTweets()
{
// oauth application keys
var oauth_token = objSiteItem.AccessToken.Rendered;
var oauth_token_secret = objSiteItem.AccessTokenSecret.Rendered;
var oauth_consumer_key = objSiteItem.ConsumerKey.Rendered;
var oauth_consumer_secret = objSiteItem.ConsumerSecret.Rendered;
var screen_name = objSiteItem.TwitterUser.Rendered;
// oauth implementation details
var oauth_version = "1.0";
var oauth_signature_method = "HMAC-SHA1";
// unique request details
var oauth_nonce = Convert.ToBase64String(
new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
var timeSpan = DateTime.UtcNow
- new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
var oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();
// message api details
var status = "Updating status via REST API if this works";
var resource_url = "https://api.twitter.com/1.1/statuses/user_timeline.json";
// create oauth signature
var baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
"&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}&screen_name={6}";
var baseString = string.Format(baseFormat,
oauth_consumer_key,
oauth_nonce,
oauth_signature_method,
oauth_timestamp,
oauth_token,
oauth_version,
Uri.EscapeDataString(screen_name)
);
baseString = string.Concat("GET&", Uri.EscapeDataString(resource_url), "&", Uri.EscapeDataString(baseString));
var compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
"&", Uri.EscapeDataString(oauth_token_secret));
string oauth_signature;
using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
{
oauth_signature = Convert.ToBase64String(hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
}
// create the request header
var headerFormat = "OAuth oauth_nonce=\"{0}\", oauth_signature_method=\"{1}\", " +
"oauth_timestamp=\"{2}\", oauth_consumer_key=\"{3}\", " +
"oauth_token=\"{4}\", oauth_signature=\"{5}\", " +
"oauth_version=\"{6}\"";
var authHeader = string.Format(headerFormat,
Uri.EscapeDataString(oauth_nonce),
Uri.EscapeDataString(oauth_signature_method),
Uri.EscapeDataString(oauth_timestamp),
Uri.EscapeDataString(oauth_consumer_key),
Uri.EscapeDataString(oauth_token),
Uri.EscapeDataString(oauth_signature),
Uri.EscapeDataString(oauth_version)
);
// make the request
ServicePointManager.Expect100Continue = false;
var postBody = "screen_name=" + Uri.EscapeDataString(screen_name);//
resource_url += "?" + postBody;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(resource_url);
request.Headers.Add("Authorization", authHeader);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
WebResponse response = request.GetResponse();
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
return responseData;
}
}
Just as you would add it into any website... create a component for it and use the twitter API like this for example: http://jsfiddle.net/abenlumley/xRwam/4/
/*********************************************************************
#### Twitter Post Fetcher! ####
Coded by Jason Mayes 2013.
www.jasonmayes.com
Please keep this disclaimer with my code if you use it. Thanks. :-)
Got feedback or questions, ask here: http://goo.gl/JinwJ
Ammended by Ben Lumley and djb31st 2013
www.dijitul.com
Ammended to display latest tweet only with links
********************************************************************/
var twitterFetcher=function(){var d=null;return{fetch:function(a,b){d=b;var c=document.createElement("script");c.type="text/javascript";c.src="http://cdn.syndication.twimg.com/widgets/timelines/"+a+"?&lang=en&callback=twitterFetcher.callback&suppress_response_codes=true&rnd="+Math.random();document.getElementsByTagName("head")[0].appendChild(c)},callback:function(a){var b=document.createElement("div");b.innerHTML=a.body;a=b.getElementsByClassName("e-entry-title");d(a)}}}();
/*
* ### HOW TO USE: ###
* Create an ID:
* Go to www.twitter.com and sign in as normal, go to your settings page.
* Go to "Widgets" on the left hand side.
* Create a new widget for "user timeline". Feel free to check "exclude replies"
* if you dont want replies in results.
* Now go back to settings page, and then go back to widgets page, you should
* see the widget you just created. Click edit.
* Now look at the URL in your web browser, you will see a long number like this:
* 345735908357048478
* Use this as your ID below instead!
*/
twitterFetcher.fetch('345190342812909568', function(tweets){
// Do what you want with your tweets here! For example:
var x = tweets.length;
var n = 0;
var element = document.getElementById('tweets');
var html = '<ul>';
if (tweets[n].innerHTML) {
html += '<li>' + tweets[n].innerHTML + '</li>';
} else {
html += '<li>' + tweets[n].textContent + '</li>';
}
n++;
html += '</ul>';
element.innerHTML = html;
});
As #IvanL said, you will simply want to create a sublayout and add the markup/JS/etc as you normally would. Below, I describe an easy-to-use library that will help you to get your Tweets via Twitter's API and also a jQuery plugin that will help simplify the way you render them. All you would need to do is wire up the library, make the necessary C# call, and then use the jQuery plugin to help you render the Tweets, using the markup style that you specify.
As mentioned below, note that I originally wrote both the library and the jQuery plugin for integration with a Sitecore 6.5 environment, and made them flexible enough to use with any solution.
Getting and Rendering Tweets
I created a C# library for the Twitter API about a year ago, named TweetNET. It has MSDN style documentation, and I built it in such a way as it could be integrated into .NET applications, and the first production site that I used it on was a Sitecore 6.5 site. The documentation and examples are pretty comprehensive, but if you have any questions, feel free to let me know.
As for the actual displaying of the Tweets after getting them from Twitter, I also have another repo, Twitter Feed, which is a jQuery plugin designed to simplify rendering Tweets. Both projects include examples of the TweetNET's use, and the Twitter Feed project also includes examples of its call, so this would be a one-stop-shop for you.
TweetNET - Latest Tweets Call
TweetNET reduces the code that you need in order to get the latest Tweets for a given handle to the following:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using TweetNET.OAuth;
using TweetNET.Requests.Timelines.Statuses;
using System.Net;
using System.IO;
public partial class _Default : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
var consumerKey = "your consumerKey";
var consumerSecret = "your consumerSecret";
var oAuthToken = "your oAuthToken";
var oAuthTokenSecret = "your oAuthTokenSecret";
var twitterHandle = "your twitter handle";
var tokens = new SecurityTokens(consumerKey, consumerSecret, oAuthToken, oAuthTokenSecret);
var utGETRequest = new UserTimelineRequest(tokens);
utGETRequest.Screen_Name = twitterHandle;
var request = utGETRequest.BuildRequest();
WebResponse response = utGETRequest.SendRequest(request);
string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
}
Twitter Feed - Rendering Tweets
$(document).ready(function () {
$("#feedTarget").twitterFeed({
count: 4,
rawData: yourRawJSONData,
prepend: "<div class='tweetWrapper'>",
append: "</div>",
tweetBodyClass: "tweetBody tweetText",
date: { prepend: "<div>", append: " - ", order: 3, cssClass: "tweetDate" },
retweet: { show: false },
favorite: { prepend: " - ", order: 0, append: "</div>" },
callbackOnEach: true,
callback: function() {
$(this).find(".tweetBody").myCallbackOnEachTweet();
}
});
});
});
To get latest tweet read following url
https://umerpasha.wordpress.com/2013/06/13/c-code-to-get-latest-tweets-using-twitter-api-1-1/