Integrating Google Search API to AC Gold

From AbleCommerce Wiki
Revision as of 06:12, 1 September 2015 by Nadeem (Talk | contribs)

Jump to: navigation, search

Google WebSearch service provides a powerful way to display search results for the customers to their own web sites. It also provides complete control over the customization and displaying search results. It is very easy to integrate Google Custom Search API in Ablecommerce. This article will discuss the integration of Google Custom Search API in ablecommerce.

First of all, we need to define a Custom Search Engine using google control panel. Here is the step by step procedure to do this:

To create a custom search engine:

  • Sign into Control Panel [1] using your Google Account (create new account if you don't already have one).
  • In the Sites to search section, add the pages you want to include in your search engine. You can include any sites you want, not just the sites you own. You can include whole site URLs or individual pages URLs. You can also use URL patterns.
  • The name of your search engine will be automatically generated based on the URLs you select. You can change this name at any time.
  • Select the language of your search engine. This defines the language of the buttons and other design elements of your search engine, but doesn't affect the actual search results.
  • Click Create.

Now the basic search engine setup is completed and ready to use. There are three required parameters that must be sent in search request, these parameters are:

1. client

The client parameter must be set to google-csbe

2. output

The output parameter specifies the format of the returned XML results; results can be returned with (xml) or without (xml_no_dtd) a reference to Google's DTD. We recommend setting this value to xml_no_dtd. Note: If you do not specify this parameter, then results will be returned in HTML instead of XML.

3. cx

The cx parameter which represents the unique ID of the CSE. This cx value can be obtained from Details section from search engine setup control panel.

For more details and adding other advanced optional parameters, visit API reference guide here [2]

Google Search Engine API Integration sample

- Create an aspx page to the root direcotry e.g. Website/GoogleSearch.aspx and add the following HTML:

<%@ Page Language="C#" MasterPageFile="~/Layouts/Fixed/OneColumn.master" Inherits="AbleCommerce.GoogleSearch" Title="Google Custom Search" CodeFile="GoogleSearch.aspx.cs" AutoEventWireup="True" %>

<asp:Content ID="MainContent" runat="server" ContentPlaceHolderID="PageContent">

Search again

           <asp:textbox id="q" runat="server" CssClass="form-control" SkinID="SrchBox" placeholder="Enter Search Keyword..." />
           
               <asp:Button ID="GoogleSearchButton" runat="server" Text="Search" class="btn-u" causesvalidation="false" OnClick="GoogleSearchButton_Click"></asp:Button>
           
               <asp:literal id="GoogleText" runat="server"></asp:literal>
                   <asp:panel id="SearchResultsPanel" runat="server" >
                       <asp:literal id="Results" runat="server"></asp:literal>
                   </asp:panel>
                   <asp:Panel ID="NoResultsPanel" runat="server" EnableViewState="false">
                       Your search did not match any documents.

Suggestions:
  • Make sure all words are spelled correctly.
  • Try different keywords.
  • Try more general keywords.
                   </asp:Panel>   
  • <asp:literal id="PaginationLinks" runat="server"></asp:literal>

</asp:Content>

Similarly, open code behind file i.e. Website/GoogleSearch.aspx.cs and place the following code:

using AbleCommerce.Code; using CommerceBuilder.Utility; using System; using System.IO; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Xml;

namespace AbleCommerce {

   public partial class GoogleSearch : CommerceBuilder.UI.AbleCommercePage
   {
       /// <summary>
       /// Variable containing the cx value provided by Google when creating a CSE
       /// </summary>
       private string _Cx;
       /// <summary>
       /// Gets or sets the cx value provided by Google when creating a CSE.
       /// </summary>
       /// <value>The cx.</value>
       public string Cx
       {
           get { return _Cx; }
           set { _Cx = value; }
       }
       public int StartIndex
       {
           get
           {
               if (Request.QueryString["s"] == null || Page.IsPostBack) return 0;
               else return AlwaysConvert.ToInt(Request.QueryString["s"]);
           }
       }
       /// <summary>
       /// Initializes a new instance of the  class.
       /// </summary>
       protected void Page_Init(object sender, EventArgs e)
       {
           _Cx = "001693589241998964910%3Aqf4ogsspcoi"; // e.g. 201699589241998965915%3Aqf4ognspcrm
       }
       /// <summary>
       /// Handles the Load event of the Page control.
       /// </summary>
       /// <param name="sender">The source of the event.</param>
       /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
       protected void Page_Load(object sender, EventArgs e)
       {
           this.Page.Form.Action = "GoogleSearch.aspx";
           if (!Page.IsPostBack && Request.QueryString["q"] != null)
           {
               q.Text = Server.HtmlEncode(StringHelper.StripHtml(Request.QueryString["q"]));
               BindResults();
               PageHelper.SetDefaultButton(q, GoogleSearchButton);
           }
       }
       protected void BindResults()
       {
           XmlDocument document = GetXML(HttpUtility.UrlEncode(q.Text), StartIndex);
           int totalResults = GetTotalResults(document);
           GoogleText.Text = String.Format("You searched:\"{0}\" Total Matches:{1}", q.Text, totalResults);
           if (totalResults > 0)
           {
               Results.Text = GetResults(document);
               PaginationLinks.Text = GetPaginationLinks(GetTotalResults(document), 10, StartIndex, HttpUtility.UrlEncode(q.Text));
               NoResultsPanel.Visible = false;
           }
           else
           {
               NoResultsPanel.Visible = true;
           }
       }
       /// <summary>
       /// Processes the URL.
       /// </summary>
       /// <param name="url">The URL.</param>
       private XmlDocument GetXML(String searchterms, int start)
       {
           String url = "http://www.google.com/search?cx=" + Cx + "&client=google-csbe&start=" + start + "&num=10&output=xml_no_dtd&q=" + searchterms;
           StringBuilder sb = new StringBuilder();
           byte[] buf = new byte[8192];
           HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
           HttpWebResponse response = (HttpWebResponse)request.GetResponse();
           Stream resStream = response.GetResponseStream();
           int count;
           do
           {
               count = resStream.Read(buf, 0, buf.Length);
               if (count != 0)
               {
                   string tempString = Encoding.ASCII.GetString(buf, 0, count);
                   sb.Append(tempString);
               }
           }
           while (count > 0);
           string document = sb.ToString();
           document = Regex.Replace(document, "\\n", "", RegexOptions.IgnoreCase);
           document = Regex.Replace(document, "=\"/custom", "=\"" + Request.FilePath, RegexOptions.IgnoreCase);
           XmlDocument xml = new XmlDocument();
           xml.LoadXml(document);
           return xml;
       }
       protected int GetTotalResults(XmlDocument xml)
       {
           if (xml != null)
           {
               XmlElement element = XmlUtility.GetElement(xml.DocumentElement, "RES", false);
               if (element != null) return AlwaysConvert.ToInt(XmlUtility.GetElement(element, "M", false).InnerText);
           }
           return 0;
       }
       protected string GetPaginationLinks(int totalResults, int totalPerPage, int startIndex, string searchterms)
       {
           StringBuilder pageLinks = new StringBuilder();
           if (totalResults >= totalPerPage)
           {
               int currentPageIndex = 1;
               if (startIndex > 0) currentPageIndex = (int)(startIndex / totalPerPage) + 1;
               //if we're not at the start
               if (currentPageIndex > 1)
               {
                   pageLinks.Append("<a href=\"?s=" + (startIndex - 10) + "&q=" + searchterms + "\">«</a>");
                   pageLinks.Append("  ");
                   // DISPLAY LINKS FOR ABOUT 5 PREVIOUS PAGES
                   int ppages = currentPageIndex - 1;
                   int i = 0;
                   if (ppages >= 10) i = ppages - 10;
                   for (; i < ppages; i++)
                   {
                       pageLinks.Append("<a href=\"?s=" + (i * 10) + "&q=" + searchterms + "\">" + (i + 1) + "</a>");
                       pageLinks.Append("  ");
                   }
               }
               if (totalResults > totalPerPage)
               {
                   // DISPLAY THE CURRENT PAGE
                   pageLinks.Append("<a href=\"?s=" + currentPageIndex + "&q=" + searchterms + "\">" + currentPageIndex + "</a>");
                   pageLinks.Append("  ");
               }
               //if where you started + 10 is NOT equal to the total number of results
               if ((startIndex + totalPerPage) < totalResults)
               {
                   // DISPLAY ABOUT 10 NEXT LINKS
                   int npages = (int)((totalResults / totalPerPage) - currentPageIndex + 1);
                   if (npages > 10) npages = 10;
                   for (int i = 0; i < npages; i++)
                   {
                       pageLinks.Append("<a href=\"?s=" + ((i + currentPageIndex) * 10) + "&q=" + searchterms + "\">" + (i + currentPageIndex + 1) + "</a>");
                       pageLinks.Append("  ");
                   }
                   pageLinks.Append("<a href=\"?s=" + (startIndex + totalPerPage) + "&q=" + searchterms + "\">»</a>");
               }
           }
           return pageLinks.ToString();
       }
       protected string GetResults(XmlDocument xdocumentml)
       {
           StringBuilder resultsBuilder = new StringBuilder();
           XmlElement RES = XmlUtility.GetElement(xdocumentml.DocumentElement, "RES", false);
           if (RES != null)
           {
               foreach (XmlElement R in RES.GetElementsByTagName("R"))
               {
                   XmlElement U = XmlUtility.GetElement(R, "U", false);
                   XmlElement T = XmlUtility.GetElement(R, "T", false);
                   XmlElement S = XmlUtility.GetElement(R, "S", false);
resultsBuilder.Append("

<a href=\"" + U.InnerText + "\">" + T.InnerText + "</a>

" + S.InnerText + "
  • " + (new Uri(U.InnerText)).Host + "

");
               }
           }
           return resultsBuilder.ToString();
       }
       protected void GoogleSearchButton_Click(object sender, EventArgs e)
       {
           Response.Redirect("~/GoogleSearch.aspx?q=" + Server.UrlEncode(q.Text));
           BindResults();
       }
   }

}

You only need to use your cx parameter value to search from your website that is provided during custom search engine setup. Now try searching some keyword, it should return the results as expected.