Guy Shahine's Blog

Converting Users to Customers

Many entrepeneurs create a landing page to put the word out about their startup. Some of them even create a facebook group to engage with their audience and then create a website or app.  One of low-fi ways is to describe what you do, 3-6 bullet point value propositions, maybe an intro video, a section about the founders and why solving this problem matters to them, a way to establish legitimacy & trust (newspaper articles mentions, current clients, etc) and a “subscribe” box to enter their email address.

Works great with consumer apps…

The subscribe by email is the hook, it allows you to capture interested users, so you can follow up with them, learn about their issues/needs and give them updates on your progress.  You keep the flow going until you potentially convert them into customers.

Setting up a basic landing page has become so popular and very easy (did you know that you host a website using dropbox?). Here are some options:

Non-technical:  launchrock.com and the likes (quora.com/What-are-the-alternatives-to-LaunchRock).

Basic knowledge of HTML/CSS: webflow.comsquarespace.com, etc

There are also tremendous amount of FREE stuff that can help you shape up your landing page nicely: fontawesome.io, coolors.copexels.com and lots of templates at html5up.netthemeforest.net, etc

… but what about enterprise?

Enterprise solutions are a little bit more complex and often require a little of customizations.  Jumping on a call with someone that can answer those questions is much easier, that’s why you sometimes notice a price tier that says “Enterprise” => Call us.

What if you don’t want to publish your phone number? And it’s definitely too early to buy a 1-800 number.  What if you just want someone to pick time on your calendar that works best for both of you. For example, on Monday & Wednesday, between 2:00pm-4:00pm, I’m available to answer any random questions from any random user that visited my landing page and is interested in learning more.

I found that embedding a schedule a demo call to action on your site or app makes the experience much better.

How can I do it?

Today, many calendar apps like Google Calendar and Office365 Calendar expose APIs for you to implement your little widget to fetch availability, book a slot, etc. Little bit of html and styling, little bit of AJAX, and an optional backend to keep the some keys as a secret and you should be all set.

Too complicated, is there a simpler approach?

I found timekit.io to provide the best experience.  Even though it’s a booking platform that’s able to accomplish much more. Using it to allow your potential customers to book time to chat with you or your team is very easy to configure and even easier to integrate.

timekit-io

There is also acuityscheduling.com but I didn’t like it as much as TimeKit

Let me know in the comments, what approach works best for you to convert interested users to customers?  Do you know about any other scheduling app?

Cheers.

Behind Resoltz.com

bannerlarge

Here’s a summary of https://www.resoltz.com technology stack, tools, libraries. I use this blog post as an agenda when I speak at events, if you’re looking for my opinion on why I chose a library vs the other, reach out to me in the comments and I’ll provide more details. An example question could be: “why did you pick Gulp over Grunt?” or “Mocha-Chai over Jasmine?”, “Azure over AWS, Google AppEngine?”

Setup

  • ASP.NET MVC 5
  • ASP.NET Web Apis
  • Asp.net identity + OWIN
  • Sql Azure
  • Azure Blob, Table and Queue storage
  • BackboneJS + UnderscoreJS
  • Typescript (soon)
  • SignalR Websockets
  • Redis Cache

Source Control

Package Managers

  • npm
  • bower
  • Nuget

Automation

Gulp

var gulp = require('gulp'),
gutil = require('gulp-util'),
del = require('del'),
jshint = require('gulp-jshint'),
less = require('gulp-less'),
batch = require('gulp-batch'),
csso = require('gulp-csso'),
csslint = require('gulp-csslint'),
csslintVisualStudioReporter = require('gulp-visual-studio-csslint');

gulp.task('jshint', function () {
  return gulp.src([paths.src.scripts, '!scripts/external/**'])  
             .pipe(jshint())  
             .pipe(jshint.reporter('jshint-stylish')); 
});

// Build tasks
gulp.task('build', ['jshint', 'less', 'cssmin'])

Asp.net Web Optimization

BundleConfig.cs
var jqueryBundle = new ScriptBundle("~/bundles/jquery",
            "https://" + cdnPath + "/scripts/jquery/2.2/jquery.min.js")
            .Include("~/bower_components/jquery/dist/jquery.js");
jqueryBundle.CdnFallbackExpression = "jQuery";
bundles.Add(jqueryBundle);
In _Layout.cshtml Template
@Scripts.RenderFormat("<script type=\"text/javascript\" src=\"{0}\"></script>", 
                      "~/bundles/jquery")
HTML output in Development
<script type="text/javascript" src="/bower_components/jquery/dist/jquery.js">
</script>
HTML output in Production
<script type="text/javascript" 
        src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js">
</script>
<script>
(jQuery)||document.write('<script src="/bundles/jquery"><\/script>');
</script>

Web.Config Transform for different deployment environments https://msdn.microsoft.com/en-us/library/dd465326(v=vs.110).aspx

image

Redirect assets to CDN with URL Rewrite

<rule name="Redirect images to cdn" enabled="true" xdt:Transform="Insert">
     <match url="content/images/(.*)" ignoreCase="true" />
   <action type="Redirect"
           url="https://az482597.vo.msecnd.net/content/images/{R:1}"
           appendQueryString="true" redirectType="Permanent" /> 
 </rule>  
 <rule name="Redirect videos to cdn" enabled="true" xdt:Transform="Insert"> 
   <match url="content/videos/(.*)" />
   <action type="Redirect" 
           url="https://az482597.vo.msecnd.net/content/videos/{R:1}"
           appendQueryString="true" redirectType="Permanent" />
 <rule>

Interesting Web.config configurations

<authorization>  
  <deny users="*" verbs="OPTIONS, PROPFIND, HEAD" />
</authorization>
<httpModules>   
 <remove name="Session" />
 <remove name="WindowsAuthentication" />
 <remove name="PassportAuthentication" />
 <remove name="Profile" />
 <remove name="AnonymousIdentification" />
 <add name="Session" type="Resoltz.FrontEnd.Modules.ResoltzSessionStateModule" />
</httpModules>
<httpCompression directory="%SystemDrive%\websites\_compressed"
 minFileSizeForComp="1024"> 
  <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />  
  <staticTypes>    
   <add mimeType="text/*" enabled="true" />     
   <add mimeType="message/*" enabled="true" />
   <add mimeType="application/javascript" enabled="true" />  
   <add mimeType="application/json" enabled="true" />     
   <add mimeType="*/*" enabled="false" />    
  </staticTypes>
</httpCompression>
<security>
 <requestFiltering>  
   <!-- Max Allowed Content Length is 10 MB-->  
   <requestLimits maxAllowedContentLength="10485760" />   
 </requestFiltering> 
</security>
<urlCompression doDynamicCompression="true" 
                doStaticCompression="true"
                dynamicCompressionBeforeCache="true" />
<httpProtocol>  
 <customHeaders>   
  <remove name="X-Powered-By" />
  <remove name="X-AspNetMvc-Version" />
  <remove name="Vary" /> 
  <add name="Vary" value="Accept-Encoding" />
  </customHeaders> 
</httpProtocol>

Client Side

HTML

Razor

  • Precompile cshtml view with RazorGenerator: Nuget package, VS extension . Will help catch errors at compile time and faster
  • Layout : Razor
  • Partial Views : Razor
  • Templating: Underscore templating

CSS

  • Less css
  • Mobile First
  • Responsive Design Media Queries

Font Icons

Javascript Libraries

  • JQuery
  • BackboneJS + UnderscoreJS (Client side framework and tools)
  • Bootstrap (Client side Grid system and default styling)
  • Modernizr (Browser feature detection)
  • Lunr (client side search)
  • Typeahead + Boodhound (autocomplete)
  • momentJS (Everything time related)
  • SignalR (Websockets made easy for realtime communication between client-server)
  • animate.css

Database

  • Locally: Sql Express
  • Production: Sql Server
  • .NET library to manage database tables and relations: Entity Framework, Code First.

Caching

Server Side

  • Redis cache http://redis.io/
  • ASP.NET caching https://msdn.microsoft.com/en-us/library/aa478965.aspx

Client Side

  • html5 local storage

Microsoft Azure

  • Web apps
  • Sql Azure
  • Storage: blob, table, queue
  • CDN
  • Traffic Manager
  • App Insights
  • Media Services
    • Encoding
    • Streaming
    • CDN
    • Media Player
  • VMs

Recommended Reading

Authentication

  • ASP.NET Identity w/ OWIN
  • OAuth
  • External using Google, Facebook, Twitter,…etc (Currently only Google is enabled)

Authorization

  • Claim Based authentication
  • Roles

CI

Email

  • SendGrid
    • Nuget: SendGrid
    • Azure SendGrid integration: Free 25,000 emails a month

Payments

  • Braintree
    • bower install braintree-web for client side minified javascript
    • Nuget: Braintree for Sever side .NET library
    • Typescript definitions (hmm, Prepared by me)

Security

Testing

.NET code: Xunit

[Fact]
public async Task AddAndGetANewUserTestShouldMatch()
{
 // Arrange    
 user = TestHelpers.CreateUser();  

 // Act       
 user = await this.fixture.UsersRepository.Add(user, "test_user_pass");
 
 // Assert            
 Assert.NotNull(user);
 using (var context = ResoltzDbContext.Create())
 {    
   var actual = context.Users.Find(user.Id); 

   Assert.NotNull(actual);      
   Assert.Equal(user.Id, actual.Id);
   Assert.Equal(user.Email, actual.Email);
   Assert.Equal(user.UserName, actual.UserName);
   Assert.Equal(user.Name, actual.Name);     
 }
}

image

Javascript: Mocha Chai

describe('Utils', function () {  
 describe('#formatDuration()', function () {
  it('should return 00:00 when the value is less than zero',
     function () {     
   utils.formatDuration(0).should.equal('00:00');
   utils.formatDuration(-1).should.equal('00:00'); 
   utils.formatDuration(-999).should.equal('00:00'); 
  });

  it('should return formatted time when the value is valid', function () {  
    utils.formatDuration(1).should.equal('00:01');     
    utils.formatDuration(60).should.equal('01:00');    
    utils.formatDuration(3599).should.equal('59:59');  
    utils.formatDuration(3600).should.equal('01:00:00');  
    utils.formatDuration(216000).should.equal('60:00:00');  
   });
  });
});

image

  • CasperJS / PhantomJS: Html & Responsive Design:
  • VS Webtests: Monitoring and acceptance testing:
  • Visual Studio Online: Loading Testing
  • Glimpse: Client Side

Deployment

  • Web Deploy
  • Powershell
  • VIP swap

Monitoring

  • App Insights
  • Web App 3 test rules
  • Web Tests
  • Azure stream logs

Analytics

  • App Insights
  • Mixpanel
  • Google Analytics
  • Facebook Pixel

User Feedback

Tasks and bugs tracking

  • Asana
  • Trello

Code Analyzers

Tools

Desktop

Web

Visual Studio Extensions

  • Bootstrap Snippet Pack
  • Disable Mouse Wheel Zoom
  • Productivity Power Tools 2015
  • Web Essentials
  • Glyphfriend
  • Bootstrap
  • GitHub for visual studio

SEO

  • Google webmaster tools
  • Bing webmaster tools
  • Schema.org
  • Facebook Graph API markup: http://ogp.me/
  • Twitter cards: https://dev.twitter.com/cards/overview

Web Performance

Goodbye Mercurial, Hello Git

After years of resistance, I recently moved all my projects to Git from Mercurial (HG).  In this post, I’ll talk about why I started with Mercurial and why Git won me over.

In 2009, I joined a new team at Microsoft called LiveLabs, back then the team was under Ray Ozzie’s org and they had an exception to use whatever tools they want, so we adopted Joel Spolsky’s tools made by his company FogCreek and Mercurial goes hand in hand with their build system Kiln and bug tracking FogBugz and wiki. Even the Mercurial tutorial is written by Spolsky http://hginit.com/

Behind the scenes: Microsoft had it’s own internal tools to manage source code, builds, bug tracking, code review, but they were all shitty. For example, we used something called Source Depot, where back then,TFS (Team Foundation Server) did not exist and Git was not endorsed by the company ”

Spent a couple of years using Mercurial until LiveLabs team got dismantled then all the other Microsoft teams that I joined, either were still using Source Depot (shoot me) or they started migrating to the brand new TFS system which is similar to SVN.  Until I joined Yammer and started using Git in a professional environment where I started to understand more the appeal and power of branching, pull requests, …etc

So Mercurial and Git are not very different, there are just some minor nuances which didn’t play a strong case for me to switch from a system that I’m already familiar and comfortable with until recently the advantages of Git over Mercurial increased and I’ll enumerate them here.

Hosting Services

Today, the winners in my opinion are GitHub for open source projects and Bitbucket for small startups, and they’re both great for established startups and large teams.  Unfortunately, FogCreek wasn’t startup friendly few years ago, I just checked the website and they’re now providing Kiln for free for up to 2 team members, and I’m not sure how long ago they’ve added that offering, positive step towards embracing startups.

GitHub: Perfect for open source projects, you can have unlimited contributors to unlimited public repositories.

Bitbucket: Perfect for small teams, you can have unlimited private repositories with up to 5 contributors for free.

Kiln: Perfect for small to large organizations? I haven’t used Kiln or Fogbugz in a while, here are the two things that I remember, it wasn’t cheap but it’s the best tools I’ve seen.  If you follow Joel’s blog and read his book “Smart and get things done”, you’ll realize that he has built an organization around the smartest and brightest engineers.

Visual Studio Online: Supports GIT and TFS. Includes a build system, load testing engine, app monitoring and analytics.

Your Own: Many systems allow you to host your own inside your organization, like github for enterprise, kiln, …etc This approach is more typical in large teams.

IDE

Xcode: Native git support, I don’t believe HG can be installed. More details here: http://www.raywenderlich.com/51351/how-to-use-git-source-control-with-xcode-in-ios-7

Microsoft Visual Studio: In Visual Studio 2015, Microsoft upped their game with an amazing native git support. Note, hg can be installed as an extension, there are some paid and some free, but they’re not as good as the native Git support. Details here: https://www.visualstudio.com/en-us/docs/git/share-your-code-in-git-vs and here https://channel9.msdn.com/posts/GitForVisualStudioTFS

Android Studio: Support for multiple source control systems, including Git, Mercurial, SVN and others. More about here: http://wii.logdown.com/posts/2013/11/15/android-studio-git-tutorial

Tools

Git Flow: Probably the best branching model I’ve personally seen in my whole career,  read more about it here http://nvie.com/posts/a-successful-git-branching-model/ . Note: There is a replica called HG flow for Mercurial, I briefly used it and faced tons of issues.

Git Credential Manager for Windows: Setting up ssh on Windows is inconvenient, I’ve used pageant for quite sometime where I wrote a script to automatically open it and load the key.  An alternative is to use http route and use the credentials manager found here https://github.com/Microsoft/Git-Credential-Manager-for-Windows to save the password.

Posh-git: A powershell environment for git, it shows which branch you’re on and supports tab auto completion

Github Desktop app:  Built by github to bring a visual interface to manage primarily your github/git repositories

Github

SourceTree: Built by Atlassian and allows you to manage your Git or Hg repositories.

SourceTree

Migration

There is an amazing guide on how to migrate from major source control systems to git, fortunately, since Git and Mercurial are very alike, the migration is very straight forward and you won’t lose your history. http://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git

In closing, I’m so far happy with my choice to adopt Git, I do miss “hg st” and “hg up”.  Let me know in the comments about your favorite git tools, also let me know if I missed something.

Happy Coding!

My Favorite Hummus Recipe

Here’s the recipe to my favorite Lebanese Hummus dish.

Before you start, you need to watch this video http://youtu.be/cLGUFaizAHs in the background while preparing your hummus paste.

Ingredients:

  •  2 cans of garbanzo beans (or 1 cup of raw garbanzo beans soaked in water & baking soda the night before.  It takes more cooking time but I recommend it)
  • 3 TBS of Tahini (preferably bought from an international deli. I recommend Cortas, Al-Wadi, Mid-East brands.  The ones from whole foods are sometimes tricky also other tahini from safeway that I didn’t like)
  • Lemon Juice of 1 1/2 lemons and separately 1/2 a lemon
  • 1~2 garlic cloves peeled and crushed (Omit if you don’t like garlic)
  • 2 pinches of Cumin Powder
  • Half-teaspoon of Salt (more salt for none canned garbanzo)
  • 1/4 teaspoon of all spices mix. (brown color mix)
  • A pinch of paprika (or more. Depends on how spicy you want it. Omit if you or your guests don’t like spicy food)

Recipe Directions:

Put the Hummus beans (Garbanzo beans) in boiling water until they become soft and you’re able to crush them easily with two finger (don’t burn your fingers), then turn off the heat and leave them sitting there for a bit, (don’t strain them from the water).  Ultimately, you should wait until the beans are warm leaning towards hot before mashing them.

In a food processor:

  1. Mince the garlic with salt first (Pulse it 3 to 4 times)2015-02-04 22.00.32
  2. Strain out garbanzo beans (don’t throw away the water, you might need it later) and process them together for about 10-15 seconds (or until the mixture stops moving).2015-02-04 21.29.31
  3. Add tahini, lemon juice and spices.
  4. Rerun the food processor and let them get all mixed up (~15 seconds)
  5. Use a spatula to mix the pieces that are stuck high on the sides
  6. Rerun for 5~10 seconds, et voila.

2015-02-04 22.06.12

If you’re lucky, they’re ready, and you’re done. 99.99% of the time, I’m not lucky and it takes some practice beyond this point the get them to be perfect, nevertheless here’s some pointers to master it:

Hummus Texture:

Perfect hummus is when it’s super smooth like cream (in Lebanon, some restaurants peel off the garbanzo skin to make it even smoother). I don’t remove the skin because you’d lose a lot of the nutrients.

Alright, let me highlight some of the issues that I’ve faced throughout my hummus making journey and my workarounds,  I’d love to hear an alternative solution in the comments.

Problem: Texture is not smooth, hummus feels thick.  You don’t want your hummus to be dry, because it will get worse by the time you serve it.

Fix: Taste it.  If it can handle more lemon, then add a bit of lemon and mix again then re-evaluate.

Problem: It still looks dry and I’ve added enough lemon.

Fix: Use some of the water that was used to cook the beans.

Problem: They feel too soft, I can even see lots of liquid on the surface.

Fix:  A thin layer of water/lemon juice is fine. Hummus will tend to dry up a bit.  If it’s too soft then add some tahini (start with 1 TBS), mix, then re-evaluate

Taste:

Problem: It tastes too lemony

Fix: Water it down with some the water that was boiled in.  Start with small amounts, mix then re-evaluate.

Problem: The tahini taste is too dominant.

Fix: Add more lemon/water. Start with lemon juice.

Problem: Tahini, Lemon, spices all taste perfect but I feel like something is missing or it’s a bit blend.

Fix: Add some salt… (but I’m trying to stay away from sodium: fine, fine, add another pinch of cumin. pinch of paprika, pinch of all-spices)

Problem: I’ve put too much garlic and I have a date.

Fix: You’re kinda screwed.  I’m not sure how you roll with the ladies but here are your options:

option a) Start over

option b) Serve it as is, it kinda sets the standard from the beginning. If she’s cool with it then she’s a keeper (Recommended)

option c) Don’t serve the hummus (leave it at room temperature, in your sad microwave. So if things don’t work out then you can destroy some before you continue with your miserable life)

Problem: I’ve put too much paprika and it’s too spicy.

Fix: Suck it up and eat.  Goat milk, plain yogurt, milk will help ease the pain.

Serving

Hummus is best served at room temperature or warm.  I like it warm. Put it in a bowl, carve a fountain with a spoon, sprinkle some olive oil and (optionally), chopped Italian parsley for looks.

Taking it to 11

On a medium heat frying pan, throw a bit of butter, some pine seeds (pine nuts, pine… whatever you want to call them) until dark brown then sprinkle them on top of your hummus dish.

Don’t get frustrated if it doesn’t work out the first time, experiment and learn. I still mess it up… sometimes

Sahteine Habibi

–Guy Shahine

 

Moving my wordpress blog without losing any content

Today I decided to move my blog from GoDaddy.com to Windows Azure Websites. In this blog post I’ll explain the goal, challenges and solutions.

Goals

1. Move all content of my previous blog from godaddy hosting to Windows Azure Websites.

2. Implement URL redirects because I wanted to change the blog address from http://gshahine.com/blog to http://blog.gshahine.com and avoid breaking any of the indexed urls by search engines or referenced by other websites.

3. Shorten url path from /archives/{year}/{month}/{day}/{post name} to post name only.

Solutions

1. I started by setting up a new wordpress blog through Windows Azure dashboard, where it was super easy to setup and here’s a detailed blog post that explains the process step by step http://sunithamk.wordpress.com/2013/11/06/migrate-your-existing-wordpress-site-to-windows-azure/

wordpress-import

2. This one was a bit tricky to choose the best approach. Couple of months ago, I moved my main page (http://gshahine.com) to run on top of asp.net mvc 4 hosted on azure websites. So I searched online for url rewrite in asp.net and found this article http://msdn.microsoft.com/en-us/library/ms972974.aspx which I skimmed through and decided to write a custom http module that listens to the “OnBeginRequest” event and manipulates the response url when the first word in the path matches “/blog” (code shared below, which includes the solution for goal #3).

fiddler

3. When I initially setup my blog in 2009, I decided to pick a path that looks like this http://gshahine.com/blog/archives/2012/11/22/dont-be-a-turkey/ , well, my SEO (Search Engine Optimization) knowledge back then was pretty limited. Recently, I got some interest in learning more about SEO (and here’s a fantastic beginner’s guide http://static.seomoz.org/files/SEOmoz-The-Beginners-Guide-To-SEO-2012.pdf). So I wanted my new URLs to look like http://blog.gshahine.com/dont-be-a-turkey . WordPress, allows you to easily update the path under Settings->permalinks where they already have a predefined option for having a path with post name only but once you update the permalinks then all the old urls would stop working and return a Not Found page. So I had to update my url rewrite logic to only pick the last part of the path when applicable.

wordpress-permalinks

Here’s my asp.net custom http module code

namespace Gshahine.com.HttpModules
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using System.Web;

    public class CustomHttpModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            var beginRequestWrapper = new EventHandlerTaskAsyncHelper(onBeginRequest);

            context.AddOnBeginRequestAsync(beginRequestWrapper.BeginEventHandler, beginRequestWrapper.EndEventHandler);
        }

        public void Dispose()
        { }

        private async Task onBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;

            if (app.Request.Path.IndexOf("/blog") == 0)
            {
                var splitPath = app.Request.Path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                string postName = splitPath.Length > 1 ? splitPath.Last() : string.Empty;

                var newUrl = new Uri(new Uri("http://blog.gshahine.com"), postName);

                app.Response.RedirectPermanent(newUrl.AbsoluteUri, true);
            }
        }
    }
}

And you need to reference your custom module in your web.config

<system.webServer>
...
Removed for brevity
...    
<modules>
      <remove name="FormsAuthentication" />
      <add name="CustomHttpModule" type="Gshahine.com.HttpModules.CustomHttpModule, Gshahine.com" preCondition="managedHandler" />
    </modules>
  </system.webServer>

I hope you find this interesting!

-guy

Seattle Times article about startup culture at Microsoft

I had a chance to meet with Janet Tu from the Seattle times newspaper to talk about how Microsoft is shifting the culture to be more innovative and quick similar to a startup culture.

The article “Startup culture stirring at Microsoft” turned out to be fantastic.

2021362211

Here are the sections where I was mentioned:

Guy Shahine works at a multibillion-dollar company that has dominated the software industry for decades and has nearly 98,000 employees worldwide.

Yet, he insists, he also works at a startup.

Shahine, in Microsoft’s Online Services Division, believes a just-launched project his Bing Advertising team is working on — linking customers’ credit cards to discount deals offered by restaurants and retailers — is essentially a startup.

“We have these ideas out there that, to some people, might sound awesome, and, to others, they think might not work out,” he said. “The only way to know is to put out those ideas, see how the market, how the customers, react to them. It’s all about experimenting, learning from those experiments, iterating.”

and…

Acting on idea

Shahine, a development lead with Microsoft’s Online Services Division, is working on Bing Offers Card-Linked, which electronically links a user’s credit card with discount deals featured on Bing Offers. When someone purchases a deal, the discount is automatically applied to their credit-card statement.

That means the user doesn’t have to carry easily misplaced coupons; or, if the offer is for 50 percent off if a customer spends $20 at a certain retailer, the offer is automatically redeemed when you ring up $20 at checkout.

“The idea was about how we can make this simpler, more customer-friendly,” Shahine said.

There were questions team members didn’t have answers to, he said, such as whether they should first attract merchants or customers. So they decided to just try putting the idea out there and getting a pulse on what works and what needs changing. Card-Linked is now up on the Bing Offers beta site.

Bing Offers, which also will be featured on Outlook.com and Skype (for customers who use the no-fee version of the service), is an example of how the company is integrating its products.

Such collaboration “is a rallying cry. We all feel it,” said Ben Gilbert, who runs The Garage, Microsoft’s initiative to encourage innovation among employees.”

Thank you Janet for this great opportunity to be featured in one of your articles.

Here’s a link to the article

http://o.seattletimes.nwsource.com/html/businesstechnology/2021362205_microsoftstartupxml.html

text only: http://seattletimes.com/text/2021362205.html

Don’t Be a Turkey

Today is Thanksgiving day, which is probably the second most popular holiday in the US where families get together and feast on a turkey, mashed potatoes, gravy and jelly, followed by a pecan or pumpkin pie with lots of whip cream. Here’s a comic about Thanksgiving by Matthew Inman http://theoatmeal.com/comics/thanksgiving.

When I hear “turkey”, it always reminds me of a story that I first read few years ago in a book called The Black Swan by Nassim Nicholas Taleb. A story that I’ve told multiple times (I have my own version now with all the salt and pepper), it goes like this: A turkey wakes up hungry, and furiously searches for food until she finds some in the corner.  Same deal the second day until she finds more food in the same spot. Fast forward few weeks, the turkey doesn’t think about food anymore, when she’s hungry she knows where to go. The turkey’s life is amazing, she’s never hungry, she can now focus on other activities until one day around the end of November, she’s snatched from her little heaven and a butcher is about to do his little business.

BingWallpaper-2012-11-22

The moment before the knife touches the turkey’s throat, she’s in shock, and she’s wondering why. How could you blame her? she didn’t do anything wrong, and there is no way she could’ve seen this coming. This goes to all of us, I smile and remember the turkey story when I hear someone saying things like “Ohh my boss said that I’m on a fast track for a high position” or “I have a stable job at company X, their stock is getting more gain”. Find a good balance in your life, don’t take shortcuts and don’t get carried away by the little details. There is a favorite quote from a Kevin Spacey movie “You can’t win a marathon without putting some bandaids on your nipples”

To help you remember not to be a turkey, I wanted to hire miss Turkey but hardee’s beat me to her http://youtu.be/qHW6QbKzJtw

Happy Thanksgiving, Don’t be a turkey my friend.

The + in Google but not Google+

If you have a gmail account like the cool kids these days, then there is an amazing feature that you didn’t know about, it’s the + feature (I’m not sure what google officially calls it), I also like to call it “catch the bastards” feature (explanation coming later).

So what is it about? Basically, you’re allowed to add a keyword, an identifier, a spell, whatever you want to call it after your username in your email address where you separate them with a ‘+’ (plus character).

Here’s an example: Let’s say I want to sign up to a new website, for instance, https://www.resoltz.com. My email address is “gshahine@gmail.com”, my username is “gshahine” so when I get asked to enter my email address, I set it to “gshahine+resoltz@gmail.com”. Now, when I receive emails from https://www.resoltz.com, they show up like this

email-Clip

How awesome is that??? I would kiss a goat right now (I look for the slightest excuse by the way Smile)

Now, you might ask me “But Guy, how would this make my life easier?”. Well, few things off the top of my head:

  1. Making your life easier is up to you and it’s all in your head.
  2. It allows you to label emails easier, for instance, adding rules for “+family”, “+friends”, “+FYI”…etc
  3. It might allow you to identify the bastards that sell your email address to entities that want to you suck your fat (ladies) or enlarge your penis (dudes).
  4. You can sound cheesy, where let’s say a beautiful lady that you just met asked for your email address to stay in touch, “gshahine+inlove@gmail.com, bamm, next thing you’ll realize is having breakfast together.

The Awesome Shift+Right Click in Windows

Sometimes it’s the small things that matter, I use my computer on a daily basis, and the fact that I work at Microsoft, my primary operating system is definitely Windows.

Working with people that are part of the organization that built the Windows OS, sometimes you learn small tricks (also called hidden features) that make your life soooo much easier (Most of those tricks are in command prompt and visual studio). You might say, “well it’s probably documented somewhere”, or if you’re more geeky, you might say “ohhh http://lifehacker.com mentioned those tricks long time ago”. Sorry to disappoint you my friend, I’m that kind of a guy that never reads the instructions manual for pretty much anything. And on many occasions I challenge myself by even not looking at the Ikea instructions to put a desk together (I just remembered how many hours I’ve spent pulling things apart and starting all over because I realized towards the end that I’ve put some screws in the wrong spot *sigh*)

Anyway, back to our main topic that’s highlighted in the title, “What’s awesome about Shift+Right click?”. Well, instead of giving you the answer, let’s play one of my favorite games that’s usually featured in newspapers, and since we’re still on missing the right spot topic Smile, it’s called “Spot the differences” (I’ll make it easy, I promise)

ok, so here’s a snapshot for a right click on a text file in Windows 7

image

And here’s a snapshot of Shift+Right click on the same file

image

Did you see it? Com’on, try harder. Ok, I promised I’ll make it easy, notice that “Pin to Start Menu” and the sneaky “Copy as path”, and here’s an example of what get’s copied to your clipboard  when you use the copy as path [“C:UsersgshahineDesktopSomeFile.txt”]. The copy as path feature is really useful when you want to share with your coworkers a file location on a shared folder or a file location in your source control enlistment. I can’t even count on my hands how many times other coworkers were surprised when they saw me pulling a copy as path while working on the projector. (Well, probably 4 or 5 times, but it sounds cheesier when you use the “can’t count on my fingers” expression, it’s makes 11 sound like sooo much Smile)

Not impressed, try it on an Excel file and discover some goodies Smile. Still not impressed?? I’m sure you don’t even smile to a maple bar donut topped with bacon. It’s those small things that matter.

Azure User Account Management

“Necessity is the mother of invention”

The Windows Azure Platform currently offers the ability to have an administrator and 10 co-administrators associated with every account (Thanks to Steve Marx’s help to figure out that number), which introduces a limitation when 11 or more team members want to share the same account. In this post, I’m going to illustrate the different ways to avoid this limitation, and I’m pretty confident that at some point in the near future the platform will support a much more sophisticated user management interface.

Some rules of thumb: Treat the account as your online banking credentials. Whoever is paying the bill should frequently keep an eye on the consumption for any suspicious activity. Periodically renew the password or refresh the management certificates, and remember that the more people that share a secret, the less secret it is 🙂

Even though we all know the rules, sometimes (in some cases, many times) we don’t follow them. So here are the different ways I’ve used to share the same account.

Share Co-Admin Credentials

One of the light overhead ways to share the account is to create a single LiveId account and give the credentials to every team member. This way everyone can login to the Windows Azure Portal as a co-administrator. To add an additional layer of safety, you can periodically change the password, this way you can avoid cases where someone left the group and still has the password or probably someone engraved the password in their favorite pub’s bathroom on a drunk night (yes ladies, you would be surprised with what’s in there)

Share A Jump Box

A jump box could be a dedicated machine or virtual machine where you save the co-admin credentials in the browser, then anyone who needs to deploy a service will have to login to the jump box with some operating system credentials. This technique is painful (imagine the process: package your service –> remote login into the machine –> copy the package and config file –> deploy through the portal) but more secure because the jump box could live under the corporate network and the credentials of the Windows Azure account are not shared with the users. Ohh by the way, only one user can be logged in to the box at a time, so depends on your team size, you might need more jump boxes.

I followed this process for like a couple of weeks until the team wide bug bash day arrived where I had to apply few fixes and deploy multiple times, and trust me I wasn’t in the best mood afterwards, the extra step of copying the files and deploying through the portal felt like ages

Share A Certificate And Subscription ID

(My favorite and most practical way)

At the moment, the Windows Azure Portal allows you to deploy a maximum of 10 certificates to your account, which will allow you to use the service management APIs to manage your account. You can create a single password protected certificate and share it with everyone on your team or you can have multiple certificates for different employees status (for instance, you can have a certificate for your full time employees, another one for contingent staff, another temporary certificate for developers who are not on the services side of the house but decided to experiment with cloud based services part of their out of the box projects. Once a user has the certificate installed on their machines and the associated Azure account subscription ID, they’ll be able to use the sweet visual studio publish button to package and deploy their service, or any of their favorite Azure Service Management Tools

Finalement (finally in French)

Sharing a certificate and subscription ID is my favorite approach because I mostly use the client side tools to deploy and manage my applications.

Please share any other ways your team applied and what you like and don’t like about them.