Browsing the archives for the Web category.


  • Anthony Stevens

The Social Media Landscape

Blogging, Community, Computing, Social Media, Software, Web

Social media and social networking represent a new paradigm in how we interact with each other online.  And it occurs to me that there are plenty of people who don’t really know what it’s all about.  So here is my subjective, partial, and opinionated of what these things are; where they came from; and how to interpret many of the things that you see when you dip your toe in the water.

FIRST: THE HISTORY

In the beginning, God created the computer.  No, wait, that’s not right.  Restarting: In the 1940′s, scientists created the first modern computer, which I think was called “BILLYGOAT” or something.  In the 1960′s, computer scientists started hooking computers together under the aegis of a Defense Department initiative called DARPA (Defense Advanced Research Projects Agency).  They called this collection of connected computers a “network”, and called this specific network the DARPANET.  Pacifists invaded, removed the “D” from the beginning, and came up with ARPANET.  This morphed into the Internet we know today, which is at its heart nothing more than a bunch (like 1,000,000,000) of computers and other devices connected to each other.

Using these primitive DARPANET and then ARPANET networks, the bearded, bespectacled geeks were able to communicate with each other using e-mail, which was like normal e-mail, only faster and with more funny characters.  Sometime in 1972, the first spam e-mail for erectile dysfunction was sent, by a Swiss researcher trying to play a trick on a colleague in Göttingen.  He was not amused.

Pretty quickly, a system called USENET was developed, which was like a bulletin board where people posted missives on programming languages, politics, and poop jokes.   USENET was set up in a hierarchy, and groups were given incomprehensible names like alt.rec.games.uk.larp.weekenders.  But using this system, the geeks were able to have this massive, worldwide, never-ending communication on any topic they chose.

USENET was really the first social-networking phenomena.

Cue the 1990′s.  In the early part of the decade, Tim Berners-Lee, who is apparently the second smartest man ever (after Stephen Hawking), created a new computer-communication protocol called HTTP, which stands for HyperText Transfer Protocol.  On top of this protocol, he built this thing called the World Wide Web, or WWW, which allowed a special computer program called a “browser” to show human-readable information, and allow you to easily allow you to link to other information.  These bits of information, called “pages” (think pages in a book), were authored by anybody who had access to a computer connected to the Internet.

I first accessed the WWW in late 1993, using a browser called Mosaic, which was written by (among other people), Marc Andreesen at the University of Illinois at Urbana-Champaign (UIUC). Marc became a billionaire co-founder of Netscape, a member of the Trilateral commission, and a celebrity dancer on “Dancing With The Stars”. (I made up at least one of those statements).

The early social interactions on the WWW were usually graphical interfaces into the much older USENET systems, or new things called “bulletin boards” or “forums”, which were like USENET for the masses.  I think the first forum post may have been a rant about the boy-band Menudo.  I’m not sure.

At some point in the next year or two, the Java programming language infected the internet with pieces of code called “applets”, and we’re still trying to disinfect ourselves.

In the mid-1990s, consumer companies got into the internet in a big way.  Amazon, EBay, Yahoo, and probably a bunch of others I’m forgetting started their online presence.  Interactions among customers was still pretty limited.  For example, early Amazon did not allow customers to rate books and write reviews.  But pretty quickly, companies found that if they involved their customers in the discussion, they got better results, more time spent on the site, and happier customers.  This was really the birth of the “social web”.

By the late 1990′s, almost everybody had an e-mail address – a way to send and receive mail across the internet – and many of us used additional means of connecting with each other, such as instant messaging (real-time chat) and even our own personal pages, which we called “home pages”.  Remember Geocities?  Yeah, neither do I, but a lot of really bad home pages found their way there in the mid-to-late 1990′s.

In the late 1990′s, every Wall Street analyst alive was screaming BUY! BUY! BUY! about any company who came out with an IPO and has some connection to the internet.  So of course, in 2000 we had a huge market correction, and many stock-option holders worth millions on paper all of a sudden became worth about zero.

A brief aside: what’s the difference between social media and social networking?  Social media in my mind is about sharing audio, video, pictures, and other creative artifacts with your network of friends (and, perhaps the public); social networking allows you to connect and communicate with others using internet-based tools and platforms.

It’s my sense that the trend is to leave behind the term “social networking” and refer to both categories of stuff as “social media”.  This is fine; the language and terminology is evolving so rapidly that in a few years we may call it something else.

SECOND: SOCIAL MEDIA BLOSSOMS

This last decade saw social media blossom as its own phenomenon.  Photo sharing sites like Flickr appeared.  Video sharing sites like YouTube launched and served up crap like William Hung singing “She Bangs”.  Audio-sharing sites let people steal music with relative impunity.  We communicated as before, with e-mail and instant messaging, but early attempts to build platforms that let us curate our network of friends and peers appeared: MySpace.  Friendster.  LinkedIn.  In 2005 or so Facebook launched and became an unstoppable force, to the point where now it serves up like 25% of the page views in the known universe.

Skype became mainstream and people all over the world can phone each other for free, or, if they are attractive, engage in video chat.

Blogging became mainstream and blogging platforms like Blogger, WordPress, and Movable Type had their moment in the sun.  Initially confined to the technocrats, blogging tools like these allowed your mom to post notes about the most recent family trip to Poughkeepsie, and thus the “mommy blogger” was born, a market segment that earns billions a year in the form of Tide and Crest sample packages.  Dave Winer milked RSS (a way to aggregate lots of blog posts together into a single usable feed) into guru status.

In 2007 Twitter came out, and all of a sudden the social media universe went fucking HAYWIRE.  We could now communicate in near-real-time with anybody, and tell them what kind of sandwich we were eating.  The 140-character limit on tweets (which is what the short messages are called) meant that we didn’t have to think about what we were writing; we just spewed it out.  For exhibitionists (like me), this was a great thing.  For grammar police, well, they’re still under heavy sedation.

The success of Twitter meant that clones were not far behind, but none of caught on.  Remember identi.ca?  Remember Plurk?  I think a company called Yammer won some TechCrunch award a couple years ago for a “corporate Twitter platform”, but I haven’t heard much.

In the late part of the last decade, mobile took off with the advent of the iPhone, which meant that all of these wonderful social-media tools and platforms we had on our computer were now with us wherever we went.  Usage exploded.  Google (with the Android platform) and Microsoft (with the Windows Mobile platform) are competing with Apple to capture market share among mobile-phone users.

THIRD: SOCIAL MEDIA TERMINOLOGY

As a social-media novice, you’re going to run into a lot of terms that are unfamiliar and which may be confusing.  Don’t worry, this doesn’t mean you’re stupid (necessarily); it means that social media has its own lingo, like the military, accounting, or porn.  Here’s a partial list of stuff I can think of off the top of my head that might be valuable:

Friend: This is someone with whom you have a reciprocal relationship, jointly agreed on.  “We’re Facebook friends” means that both you and the other person have agreed to be in each other’s friend list and have special access to each other’s profiles and shared items.

Connection: Like a friend, but used more in a professional sense, such as on LinkedIn.

Follower: This is a one-way relationship in which I can follow you, but you don’t necessarily follow me.  This is common on Twitter, where a billion people will follow Ashton Kutcher even though he doesn’t know you and doesn’t give two shits about you.

Follower Count: This is the number of people that follow your Twitter stream.  Some people obssess about the ratio of how many people they follow vs. how many people follow them.  This metric is a proxy for penis length and is not worth discussing. Note: I have a long good ratio.

OH: This is short for “Overheard”, and people will preface tweets or Facebook posts with “OH” when they hear something funny and want to pass it along.

RT: This stands for “Retweet”, and is used when I want to share something you’ve posted with my own followers.  It’s a mark of respect, and some douchey social-media gurus think their entire self-worth is described by how many retweets they get a day.

TMI: An acronym for “Too Much Information”, and is used when you feel like someone has overshared; such as describing the characteristics of their cold sore, or the consistency of their bowel movements.

DM: An acryonym for “direct message”, this is a private message shared between two people.  Sometimes you’ll hear people say “DM me” or “D me” if they’re asking for a private message.  Since Twitter used the shorter “d” for a direct-message command, you have a group of people used to the “dm” command to send hilarious direct messages to their entire follower list, and the site dmfail.com was born.

@: if you’re referring to someone else on twitter, you preface their Twitter username with an “@” character, so they will see the post and be included in the conversation.  Sometimes you’ll hear the phrase “at me”, which means you’re asking someone to send you a public message on Twitter.

URL Shorteners: because the Twitter only allows 140 characters, there are a million services that take a long URL link and shorten it into a few characters, leaving you more room to describe your ham sandwich.  Bit.ly is probably the most famous, but choose your own poison.

Social Media Douchebag: This is a special type of person who turns everyone off with (a) their transparent attempts to inflate their follower counts (b) attempts to convince people of their expertise, even if not warranted, (c) their endless inside-baseball terminology and anecdotes, or (d) starfucking celebrity references.  You do not want to be a social media douchebag.

Community Manager: this is a person whose role is to interact with the community online and sort of act as a liaison between the internet and the company.  It’s sort of like a junior marketing position, but an increasingly important position, as the conversation about a company can turn nasty and amped very quickly.  A good community manager is attentive and inclusive and very, very high-energy.

Likes: Both Facebook and Twitter allow you to like (sometimes referred to as “favorite” certain posts or pages that strike you as worthy for whatever reason.  Different people have different criteria for liking something.

I’ll close this post with a few observations:

Google, the juggernaut of the internet, barely comes in for a mention in this condensed review of the social-media landscape.  That’s partly because Google’s main revenue source is advertisements, and as long as you’re on the internet, you’re probably making Google money, whether it’s searching,blogging, Tweeting, or Facebooking.

I’ve made no mention of the privacy concerns surrounding social media.  That’s partly because I don’t particularly care about privacy, and also partly because there are no pictures of me frenching a fraternity brother after the Spring Kegger.  Extant.  I should add “extant”.

I’ve focused a lot on Facebook and Twitter as the behemoths of the social-media landscape, but there are a million ways to connect online and lots of interesting things going on.  If you’re endlessly curious about people and don’t mind new technology, social media is a great place for you.

Did you like this post?  Would you like to see more like this?   Let me know in the comments!

Comments Off

Twitter SMS: Then Came The Deluge

Social Media, Twitter, Web

I like the word “deluge” – it’s unusual, infrequently used, and brings to mind (for me) both the word “Luge”, which is a fun sport to watch in the Winter Olympics, and the word “Deluxe”, which makes me think of a great cheesburger.

Anyway.  I’m writing today about Twitter SMS notifications.

I turned on the global “Send me SMS notifications” option a couple days ago, and my phone started buzzing madly.  Within a few minutes I had dozens of texts with tweets from people I follow on Twitter.  “But wait!" I cried.  “I didn’t want SMS from *everybody*, just the people I explicitly opt-in to!”

Here’s what I think happened.

About a year ago, I turned on that global notification, and quickly turned it off due to the volume of texts.  At some point, Twitter maybe changed their API or schema or something, so that when I turned it on again on Monday, all the people I was following back then were in my “opt-in” list.  I conclude this because I was only getting texts for people that I’ve followed for quite a while – no new tweeps seemed to be in my opt-in list.

So, for a while I painstakingly went through the Twitter web UI to turn off the text messages for each user I didn’t want to hear from, using the little cell-phone icon present in the user’s profile page:

image

If you click that icon it will toggle notifications on or off.

Then, I realized that the SMS interface probably has options, and sure enough, if you reply OFF <username> to the Twitter SMS number, it will turn notifications off for that user.  So I switched to that method, which was faster and allowed me to kill the notifications right when I received them.

At this point, I’m only receiving notifications from people I want to hear from.

It would be nice if Twitter provided a web page to manage notifications in batch – or a “turn everyone off” option that doesn’t also turn off notifications in general.  Then you could start opting in to people you want, from a blank slate, so to speak.

Comments Off

Plaintext Passwords? Really, New Yorker?

Web

This is not OK:

newyorker.plaintext.password

The New Yorker magazine, or their digital arm, or their subscription vendor (it’s hard to figure out exactly who), sent me an e-mail with my password in plaintext.  My original password, and one that I happen to use for several other subscription-based sites.

Attention New Yorker: please send this along to your security person(s) and ask them to research acceptable workflows by which a user obtains or resets their password. Because it’s for good goddamn sure that they don’t have a clue right now.

Sincerely,

Me

Comments Off

Twitter Etiquette

Community, Networking, Web

First rule of Twitter etiquette: there is no such thing.  In my opinion, if you don’t like something that someone is doing, you can unfollow them anytime you want.

Having said that, what are some of the new themes in Twitter etiquette that are worth commenting on?  Let’s take a tour.

#hashtags: Hashtags are those words prefixed by the pound sign (“#”, also known a hash sign) that you see in tweetstreams.  They supposedly provide context and metadata to tweets, but in practice, I see them used mostly for emphasis, and that’s how I use them.  It’s slightly painful to see well-meaning twitterati try to coordinate hashtags for an event when everyone has already started using different ones.

Blog posts: Normally people are pretty good about noting that they are linking to one of their own posts by prefixing their tweet with [blog] or [post] or something similar.  Bloggers who repeatedly spam their own posts get blocked, period.  Twitter in my mind is a lifestreaming app, not a one-way push mechanism.

Retweets: Twitter recently fucked up the retweet function on their website, and not only don’t allow you to edit tweets for length, or add your own prefix comment.  Luckily most other tools still allow you retweet and  keep your sanity.  A couple tricky issues with retweets:

  • How much editing is too much?
  • If an item has been retweeted before it got to you, do you have to keep the whole chain of retweeters?

I have no hard-and-fast expectation for either.  If you want to edit the retweet, go for it.  If you want to chop out multiple retweeters, go for it.  Try your best to keep original attribution, but don’t go all haywire applying severe rules to a fluid medium.

Grammar: A lot of twitter grammarians have already checked themselves in to inpatient psych wards, so this problem is less of an issue than it used to be.  Twitter grammar sucks.  People type quickly, they type while driving, they type while roller skating backwards and locking lips with their significant others.  Bad grammar happens.  Even if bad grammar chafes (as it does me), you can learn to deal with it.  People are messy. So is Twitter.

Rickrolling:  Rickrolling is like heavy drinking; every now and then it can be a fun break.  Do it every day and people start to shun you.

Protected Updates: My favorite phrase on this question is “protected updates make baby Jesus cry.”  Don’t protect your updates and still pretend that you’re “doing” Twitter.  Get over your fear of the Wayback Machine, live your life authentically, and don’t worry what some future boss/friend/spouse might think about something you tweeted back in 2008.

Inanity: Sometimes tweets make no sense.  In my opinion, that’s part of the fun of Twitter; you get to see people as they really are, without a lot of filtering and polishing and pre-planning and run-this-by-my-publicist checking.  Tweeps who are too polished are boring, IMHO.  On the other hand, if you like the  corporate flavors, feel free to unfollow someone who tweets about the junk that their cat just threw up.

Anything to add?  Things you love or hate about Twitter?  Write it in the comments!

2 Comments

Widgets, Widgets, Widgets

Software, Web

I’m going to start looking closely at widget technology.  Not widget as in “doodad: something unspecified whose name is either forgotten or not known”, but widget as in “a live update on a website, webpage, or desktop.”  I have been thinking for some time about using widgets as part of a distribution strategy for Crowdify, and a recent phone call convinced me to jump on the ball and get the tech done.

So, what’s a widget, really?  It’s something that:

a) publishers (using that term VERY broadly) can get;

b) runs on a webpage;

c) dynamically pulls content at render-time from a source location;

d) (optionally) uses JavaScript to do snazzy UI effects;

e) (optionally) allows website visitors to interact with them

The user views the widget contents, interacts with the widget by clicking or what-have-you, and hopefully does whatever the widget provider wanted them to do in the first place.  For Crowdify, that will mean clicking on terms and submitting them.

You can think of banner ads as a widget, using definitions (a) through (c), above.  I’m more interested in examples of fully-interactive widgets, since that’s what I’ll need for Crowdify.

So what sorts of architectures can one use for widgets?  (I’m talking the display of the widget on the publisher’s site, not the getting of the widget code in the first place).

  • Well, <IFRAME>s are deprecated all to hell, and for good reason.  Next.
  • I see a lot of <script> tags that pull HTML content back from a dynamic source, i.e. PHP or ASPX code.  This is the “server proxy” approach.
  • I also see lots of widgets that use a <script> tag that pulls from a remote .js script.  Similar deal as the above, but makes heavier use of JavaScript to render results.  This is the “script tag” approach.
  • You can make Flash widgets that load from a remote host.
  • I’m sure, without checking, that I could do a Silverlight widget.
  • What is this JSONP business?  It’s a way to do Ajax calls without getting drilled by XSS restrictions.  I’m not sure what advantages this has over the server proxy approach, other than the “cool factor”.  Maybe performance?  Agility/more flexibility for API callers?  I need to look into this a bit more.

Enough for now.  More widget research later.

Comments Off

Google Real-Time Search Results

Web

Google’s real-time search results are starting to be shown at the top of the search engine results pages.  Here’s a search I did today for “balsamiq”.

image

I like it.  I hope that the interface doesn’t get too cluttered, and of course I REALLY hope that the relevance stays high.  But it’s a natural, necessary next step to incorporate the Real Time Web into the results.

What does it all mean?  I’ll leave that discussion for people who have time to think deeply on the subject, or perhaps I’ll carve out some time for a Seattle 2.0 blog post on the subject.

Comments Off

Twilio Demo #3: Appointment Reminder using the REST API

Software, Web

My last Twilio demo showed how you could call Twilio and retrieve information from a web application you’ve built.  This demo shows the reverse scenario: you use a web application that calls out to Twilio, which in turn calls out to a given phone number.

This will be a pretty straightforward translation of Twilio’s existing Appointment Reminder demo, which is written in Ruby.

WARNING: Use this power only for good.  For example, you wouldn’t dream of rickrolling anyone, would you? :)

Let’s get started.  Our web app will be written in ASP.NET/C#, and, unlike the previous example, has no database backend, for simplicity’s sake.  In a real-life application, you would pull these reminders from a database on a schedule; but here we’ll bypass that part.

Before you get started, you’ll need to download the C# REST helper library from the Twilio website. This contains some code that wraps the messy network communications.

Add the file twiliorest.cs to your web application project.

You’ll need two ASPX pages: a page that captures the phone number you want Twilio to call, and a page that Twilio uses to decide what to do based on the callee’s responses.

Here’s the web form to capture input. Put this in your <form> tag in a new web form page called default.aspx:

Twilio phone reminder demo

Enter your phone number to receive an automated reminder

Here’s the code-behind in default.aspx.cs:

using System;
using System.Collections;
using TwilioRest;

namespace Twilio.Web.appointment
{
    public partial class _default : System.Web.UI.Page
    {
	protected const string ACCOUNT_SID = "SSSSSSSSSSSSSSSSSSSSSSSSSSSSS";
        protected const string AUTH_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        protected const string API_VERSION = "2008-08-01";
        protected const string CALLER_ID = "NNN-NNN-NNNN";

        protected void SubmitButton_Click(object sender, EventArgs e)
        {
            string phoneNumber = Server.HtmlEncode(this.PhoneNumberText.Text);
            this.MakeTwilioCall(phoneNumber);
        }

        protected virtual void MakeTwilioCall(string phoneNumber)
        {
            TwilioRest.Account account = new Account(ACCOUNT_SID, AUTH_TOKEN);

            // create the URL at Twilio to post to
            string postUrl = "/{0}/Accounts/{1}/Calls";
            postUrl = string.Format(postUrl, API_VERSION, ACCOUNT_SID);

            // create the variables to pass in to the POST
            string reminderUrl = Page.Request.Url.GetLeftPart(UriPartial.Authority) + "/appointment/reminder.aspx";
            Hashtable vars = new Hashtable(3);
            vars.Add("Caller", CALLER_ID);
            vars.Add("Called", phoneNumber);
            vars.Add("Url", reminderUrl);
            try
            {
                string response = account.request(postUrl, "POST", vars);
            }
            catch (Exception exc)
            {
                this.MessageElement.InnerText = exc.Message;
            }
        }
    }
}

What we’re doing here is simply handling the button click event and then using the Twilio helper library to make the RESTful call to the Twilio servers. Of course you need to put your own values in for ACCOUNT_SID, AUTH_TOKEN, and CALLER_ID, which you can get from your Account page on the Twilio website.

Twilio will call the phone number you enter in the text box, and use a new page /appointment/reminder.aspx (which you have to create) as the “controller” for the outbound call.

Your reminder.aspx page should be blank (since you will be writing XML output, not HTML). Here’s the code-behind for reminder.aspx:

using System;
using System.Collections;
using System.Xml;

namespace Twilio.Web.appointment
{
    public partial class reminder : System.Web.UI.Page
    {
        protected string Url = null;

        protected void Page_Load(object sender, EventArgs e)
        {
            Page.Response.ContentType = "text/xml";
            this.Url = Page.Request.Url.GetLeftPart(UriPartial.Authority) + "/appointment/reminder.aspx";

            if (Request["Digits"] != null)
            {
                DoAction(int.Parse(Request["Digits"].ToString()));
            }
            else
            {
                this.WriteReminder();
            }
        }

        protected virtual void DoAction(int digit)
        {
            switch (digit)
            {
                case 3:
                    {
                        WriteGoodbye();
                        break;
                    }
                case 2:
                    {
                        WriteDirections();
                        break;
                    }
                default:
                    {
                        WriteReminder();
                        break;
                    }
            }
        }

        protected virtual void WriteGoodbye()
        {
            this.WriteXmlToResponse("goodbye.xml", null);
        }

        protected virtual void WriteDirections()
        {
            this.WriteXmlToResponse("directions.xml", new string[1] { this.Url });
        }

        protected virtual void WriteReminder()
        {
            this.WriteXmlToResponse("reminder.xml", new string[1] { this.Url });

        }

        /// 
        /// XML helper method
        /// 
        protected virtual void WriteXmlToResponse(string fileName, string[] values)
        {
            System.Xml.XmlDocument doc = new XmlDocument();
            string path = Server.MapPath(Page.Request.ApplicationPath) + @"\appointment\" + fileName;
            doc.Load(path);
            string xml = doc.OuterXml;
            xml = string.Format(xml, values);
            Response.Write(xml);
        }
    }
}

We’re using the same WriteXmlToResponse() helper method we created in our last demo. There are three output functions: WriteReminder(), WriteDirections(), and WriteGoodbye(), which correspond to the three choices the user can make when they receive the phone call.

Also note that we set the MIME content-type to “text/xml” in the first line of Page_Load().

Not much to it, is there?

To make this demo work, you’ll also need three XML files that contain the content to read to the user:

reminder.xml


			Hello this is a call from Crowdify.  You have an appointment tomorrow at 9 AM.

			Please press 1 to repeat this menu. Press 2 for directions.	Or press 3 if you are done.

directions.xml


	Your appointment is located on the top of Mount Everest.
	{0}

goodbye.xml


	Good bye.

Note that in the first two XML files we are using the same String.Format() placeholders as in our previous demo.

That’s it – an end-to-end demo of using the Twilio REST API. The helper library that Twilio provides makes it really easy to get going in no time at all.

UPDATE: I’ve zipped the source (which includes code for all three recent Twilio demos) and saved it at http://thepursuitofalife.com/wp-content/uploads/2009/01/twilio-demo.zip.

Technorati Tags: ,,

8 Comments

Twilio Company Directory Example

Software, Web

Moving on from the very simple “Hello, World” sample I discussed in my last post, I’ll now describe how to create a simple company directory application that uses Twilio in ASP.NET, C#, LINQ, and SQL Server.

This sample is translated pretty directly from the PHP example found on the Twilio demo page.

Unlike the last sample, this one actually uses some C# code-behind and has a backing database to look up and retrieve information.

OK, let’s begin with the database code. Open SQL Server Management Studio and create a new table called directory. You can do this manually via the GUI, or you can run this script:

create table directory
(
	extension varchar(12) NOT NULL PRIMARY KEY CLUSTERED,
	phone_number varchar(30)
)

Insert data into your new table using the following script:

INSERT INTO directory (extension, phone_number) values (“0”, “206-555-1212”)
INSERT INTO directory (extension, phone_number) values (“1234”, “206-555-3434”)

Using  Visual Studio, create a new C# web application project.

Add a new LINQ to SQL file called twilio_demo.dbml.  This will contain the LINQ mappings between your ASP.NET application and your database.

In the Server Explorer, add a new data connection by right-clicking the Data Connections folder and selecting Add Connection.

image

This will show you the Add Connection dialog:

clip_image001

Open the DBML file in the editor.

In the Server explorer, drill down through your new data connection to the Tables node.  You should see a single table called directory.

Using your mouse, drag the table to your DBML editor pane.  You’ll see a visual representation in the editor like so:

image

Next, you need to set up your content.  I opted to create separate XML files for this purpose, rather than writing the XML inline.  To do this, create three XML files as follows:

initial_greeting.xml



	
		Thank you for calling Crowdify.
		
			If you know your party's extension, please enter it now,
			followed by the pound sign.  Otherwise, stay on the line for the receptionist.
		
	
	Connecting you to the operator, please stay on the line
	
		{0}
	

dialing.xml



	Thank you, dialing now
	
		{0}
	

not_found.xml



	
		I'm sorry, we couldn't find the extension {0}.
		
			If you know your party's extension, please enter it now,
			followed by the pound sign.  Otherwise, stay on the line for the receptionist.
		
	
	Connecting you to the operator, please stay on the line
	
		{1}
	

You’ll notice that these XML files have string placeholders of the format {n}, into which we’ll put the dynamically-retrieved information from the database.  You could do this in a more type-safe way by using XSLT and passing parameters, but we’ll stay simple for now.

Now you’re ready to code your page that will handle the incoming Twilio requests.  Add a new ASPX page called default.aspx.

Open the file in the HTML editor and delete everything but the <%@ Page %> directive.  This is because this file will be displaying XML and we don’t want any of the default HTML hanging around.

To set up your file for displaying the correct MIME content-type, add this line to your Page_Load() method:

Page.ContentType = “text/xml”;

Now for the rest of the code.  For brevity, I’ll display the whole code of the default.aspx.cs file below, and comment afterward.

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml;
using System.Xml.Linq;

namespace Twilio.Web.directory_simple
{
    public partial class _default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Page.Response.ContentType = "text/xml";
            string extension = this.GetExtensionFromRequest();
            string receptionistNumber = this.GetReceptionistNumber();
                
            if (extension == null)
            {
                this.WriteInitialGreeting(receptionistNumber);
            }
            else
            {
                string number = this.GetPhoneNumberByExtension(extension);
                if (number != null)
                {
                    this.WriteDialing(number);
                }
                else
                {
                    this.WriteNotFound(extension, receptionistNumber);
                }
            }
        }

        /// 
        /// Page POST variable retreival
        /// 
        protected virtual string GetExtensionFromRequest()
        {
            string extension = null;
            object digits = Request["Digits"];
            if (digits != null)
            {
                extension = digits.ToString();
            }
            return extension;
        }

        /// 
        /// XML helper method
        /// 
        protected virtual void WriteXmlToResponse(string fileName, string[] values)
        {
            System.Xml.XmlDocument doc = new XmlDocument();
            string path = Server.MapPath(Page.Request.ApplicationPath) + @"\directory_simple\" + fileName;
            doc.Load(path);
            string xml = doc.OuterXml;
            xml = string.Format(xml, values);
            Response.Write(xml);
        }

        #region Database Methods

        protected virtual string GetPhoneNumberByExtension(string extension)
        {
            string phone = null;
            string connString = ConfigurationManager.ConnectionStrings["twilio_demoConnectionString"].ConnectionString;
            using (twilio_directoryDataContext tdc = new twilio_directoryDataContext(connString))
            {
                var item = tdc.directories.SingleOrDefault(x => x.extension == extension);
                if (item != null)
                {
                    phone = item.phone_number;
                }
            }

            return phone;
        }

        protected virtual string GetReceptionistNumber()
        {
            return this.GetPhoneNumberByExtension("0");
        }

        #endregion

        #region Write Methods

        protected virtual void WriteInitialGreeting(string receptionistNumber)
        {
            this.WriteXmlToResponse("initial_response.xml", new string[1] { receptionistNumber });
        }

        protected virtual void WriteDialing(string number)
        {
            this.WriteXmlToResponse("dialing.xml", new string[1] { number });
        }

        protected virtual void WriteNotFound(string number, string receptionistNumber)
        {
            this.WriteXmlToResponse("not_found.xml", new string[2] { number, receptionistNumber });
        }

        #endregion

    }
}

Comments about this code:

In order to use the ConfigurationManager class, you need to add a reference to System.Configuration, version 2.0.50727, via the Add References dialog.

You’ll see the method GetPhoneNumberFromExtension uses the LINQ data context that was created automatically when you created your .DBML file. LINQ makes data access incredibly easy.

The Page_Load() method contains some simple logic to write out the appropriate XML content based on whether or not we’ve gotten a Digits parameter via the Post variable. I intentionally left it open to retrieving QueryString variables as well, for debugging purposes.

The XML writing helper method is self-explanatory. Note that the code for this example lives in a /directory_simple/ subdirectory of my web application.

The Connection String information was generated for you when you created your twilio_demo DBML file. It’s placed by default in the web.config file:


		
	

Once you compile and deploy your web application (including the XML files), you can dial your Twilio number and work your way through the possible workflows:

  • Initial greeting; enter an extension
  • Initial greeting; wait for receptionist
  • Extension not found
  • Extension found; dialing

Again, this is a fairly simple example that doesn’t begin to tap the full power of Twilio, but shows you how to get going with a simple database-driven telephony app.

Technorati Tags:

4 Comments

Twilio Simple “Hello, World!” Demo

Software, Web

I’ve been fooling around with a very powerful telephony-enabling technology called Twilio and did a couple demos in ASP.NET and C# today.

The first one is a simple “Hello, World” demo that shows how you can tie your Twilio phone number to a simple recording that is served up by your website.

Here are the steps:

  • In Visual Studio 2008, create a new Web Application Project called “Twilio.Web”.
  • Include an new XML file called helloworld.xml.
  • The contents of helloworld.xml should be:


    Hello world.

  • Compile and deploy your web application
  • Go to twilio.com and in your Account settings, point the "Uses Url" url to your XML file:

image

When you dial your Twilio phone number and enter your pin, the automated voice should say “Hello world.” to you.

Piece of cake.

Technorati Tags: ,,

Comments Off

Great Greasemonkey Script Extends Bio Information For Twitter Friends and Followers

Twitter, Web

Hat tip to Marjolein Hoekstra for this link to Twitter Friends’ Bio at a Glance, a greasemonkey script that adds additional information to your friend and follower lists at twitter.com.

Even if you don’t use twitter.com for tweets, it’s a handy place to review who follows you and whom you follow.  With this extra script, it becomes even handier!

Screenie:

image

Technorati Tags: ,

3 Comments
« Older Posts
Newer Posts »