65.9K
CodeProject 正在变化。 阅读更多。
Home

Google 日历事件中的 IVR 应用

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.20/5 (5投票s)

2008 年 7 月 7 日

CPOL

5分钟阅读

viewsIcon

44471

downloadIcon

397

当Google日历中的事件发生时,通过IVR呼叫用户


关于IVRGoogle日历的介绍

许多人都使用日历的经历,它确实方便了我们的工作和生活。但大多数日历都基于文本提醒,这意味着您只能在电脑前收到事件提醒。

所以我认为如果日历能通过电话提醒我。如果我想实现这个想法,我需要一个能提供API的日历,以及一种能通过编程进行呼叫的技术。

幸运的是,这些技术都已经提供了,Google日历IVRInteractive Voice Response,交互式语音应答,基于电话呼叫)。

我写了一些文章介绍IVR。您可以在这里查看

Voicent Gateway中使用的IVR
Facebook中使用的IVR

或者,您可以通过Google搜索进行研究,有很多文章介绍它。现在,我们将主要关注Google日历。

Google日历允许客户端应用程序以Google数据API("GData")feed的形式查看和更新日历事件。您的客户端应用程序可以使用Google日历数据API创建新事件,编辑或删除现有事件,以及查询符合特定条件的事件。

日历数据API有许多可能的用途。例如,您可以创建一个用于您团队日历的Web前端,并将Google日历作为后端。或者,您可以根据您组织的事件数据库为Google日历生成一个公共日历进行显示。或者,您可以搜索相关的日历,在这些日历上显示即将发生的事件列表。

您可以阅读这些文章来理解Google日历

什么是Google数据API?

Google数据API客户端库

Google数据API示例

开发者指南

这些文章提供了使用.NET客户端库处理Google日历服务的详细介绍和示例。有关设置客户端库的帮助,请参阅入门指南。您将找到添加事件、更新事件、删除事件和查询事件的示例。如果您有兴趣了解更多关于.NET客户端库用于与日历数据API交互的底层协议,请参阅协议选项卡

阅读完这些之后,您可以继续以下主题。

如何创建日历服务

CalendarService类代表与日历服务的客户端连接(包括身份验证)。要使用.NET客户端库请求feed,首先实例化一个新的CalendarService对象并对用户进行身份验证。然后使用Query方法检索包含用户所有日历条目的CalendarFeed对象。

您可以通过WebForm或WinForm对用户进行身份验证,WebForm称为
AuthSub代理身份验证,而WinForm称为ClientLogin用户名/密码身份验证。

为了通过AuthSub登录协议对应用程序进行身份验证,您必须获取会话令牌。

首先,为您的应用程序构建一个AuthSubRequest URL,并像下面这样调用.NET客户端库
AuthSubUtil.getRequestUrl("http://www.example.com/RetrieveToken",
                          "http://www.google.com/calendar/feeds/",
                                                        false,
                                                        true);

getRequestUrl方法接受几个参数

  • "next" URL,即用户登录其帐户并授予访问权限后,Google将重定向到的URL;
  • scope,如上一节所述;
  • 两个布尔值,一个指示令牌是否将在注册模式下使用,另一个指示令牌之后是否将兑换为会话令牌。

上面的示例显示了一个在未注册模式下(第一个布尔值为false)的调用,用于稍后将兑换为会话令牌的令牌(第二个布尔值为true);请根据您的应用程序相应地调整布尔值。

用户在点击Google的AuthSub页面链接并登录后,AuthSub系统会使用您提供的"next" URL将用户重定向回您的应用程序。

当Google重定向回您的应用程序时,令牌会作为查询参数附加到"next" URL。因此,在上面的"next" URL的情况下,用户登录后,Google会重定向到一个类似http://www.example.com/RetrieveToken?token=DQAADKEDE的URL。因此,令牌可以在ASP页面的Request.QueryString对象中作为变量访问。

您最初检索到的令牌始终是单次使用的令牌。您可以按照AuthSub文档中的描述,通过AuthSubSessionToken URL将此令牌兑换为会话令牌。您的应用程序可以使用.NET客户端库进行此兑换,如下所示

Session["sessionToken"] = 
                AuthSubUtil.exchangeForSessionToken(Request.QueryString["token"], null); 

现在,您可以通过将令牌放在Authorization头中,使用会话令牌对日历服务器的请求进行身份验证。

GAuthSubRequestFactory authFactory = 
                new GAuthSubRequestFactory("cl", "CalendarSampleApp");
authFactory.Token = Session["sessionToken"].ToString();
Service service = new Service("cl", authFactory.ApplicationName);
service.RequestFactory = authFactory; 

要使用ClientLogin,请调用CalendarServicesetUserCredentials方法,指定您的客户端代表其发送查询的用户ID和密码。例如

CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
myService.setUserCredentials("jo@gmail.com", "mypassword");

您可以通过向allcalendars feed URL发送一个经过身份验证的GET请求来获取用户日历的列表

http://www.google.com/calendar/feeds/default/allcalendars/full 

您也可以查询以检索经过身份验证的用户有权访问的日历列表

http://www.google.com/calendar/feeds/default/owncalendars/full 

在实例化一个新的CalendarService对象并对用户进行身份验证后,然后使用Query方法检索包含用户所有日历条目的CalendarFeed对象。

// Create a CalenderService and authenticate
CalendarService myService = new CalendarService("exampleCo-exampleApp-1");
/*The parameter applicationName in the constructor of CalendarService is random,
you can enter any name you want.*/
myService.setUserCredentials("jo@gmail.com", "mypassword");

CalendarQuery query = new CalendarQuery();
query.Uri = new Uri("http://www.google.com/calendar/feeds/default/allcalendars/full");
CalendarFeed resultFeed = service.Query(query);
Console.WriteLine("Your calendars:\n");
foreach (CalendarEntry entry in resultFeed.Entries)
{
    Console.WriteLine(entry.Title.Text + "\n");
}

CalendarService是获取Google日历服务的关键,完成之后,您就可以得到您想要的东西了。在下一个主题中,我将按照这个方法获取日历事件的开始时间,并使用IVR进行呼叫。

事件发生时呼叫用户

我的想法是,首先从客户端使用JavaScript回调到服务器端。在服务器端,使用CalendarService查询从Calendar Service检索EventEntry的StartTime。然后将时间字符串返回给客户端,在客户端,使用JavaScript方法setTimeout循环检查返回的时间与客户端时间。当它们相等时,返回到服务器端,构建一个IVR对象来呼叫用户。

这是html代码

 <head id="Head1" runat="server">
    <title>GetGoogleEvent</title>
    <script language="javascript" type="text/javascript">
    
    var stopTimmer;//Timeout ID
    var strReturn;//The value returned from the server
    
    function ReceiveDateFromServer(valueReturnFromServer)
    {
        document.getElementById("ServerTime").innerHTML = "DateTime of Server:"
        + valueReturnFromServer;
        
        strReturn = valueReturnFromServer;
        
        //Start the reminder to remind the user about the Calendar Event.
        TriggerEvent();
    }
    
    function GetServerTime(format)
    {
        CallBackToServer(format, "");//Send callback to server.
    }
    
    function TriggerEvent()
    {
        //Get the current date with US culture.
        var localDate = Date.parse((new Date()).toString("en-US"));
        document.getElementById('NowTime').innerHTML = "DateTime of Now:" 
                 + (new Date()).toString("en-US");
        
        var serverDate = Date.parse(strReturn);
        var diff = localDate - serverDate;
        //Compare the date returned from server with the client date.
        if (diff >= 0)
        {
            /*If the client is on time,
            then clear the Timeout and start the server event to call user.*/
            
            clearTimeout(stopTimmer);
            
            var btnCall = document.getElementById('btnCall');
            if (btnCall != null)
            {
                btnCall.click();//Call the server event to make a call.
            }
            
            return false;
        }
        
        /*Recurrence,check every 1 second,
         until the current time equals the time returned from Calendar.*/
        stopTimmer = setTimeout("TriggerEvent()", 1000);
    }
    
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Button ID="btnStartReminder" runat="server" Text="Start Reminder" 
        OnClientClick="javascript:GetServerTime('');return false;" />
        <br />
        
        <br />
        <span id="ServerTime">
            DateTime of Now<%= DateTime.Now.ToString("yyyy-MM-dd HHHH:mm:ss") %>
        </span>
        <br />
        
        <span id="NowTime"></span>
        
        <div style="display:none">
            <asp:Button ID="btnCall" runat="server" onclick="CallUser" Text="Button" />
        </div>
    </div>
    </form>
</body>
        

这是代码隐藏

您需要以下using语句

using System.Globalization;
using Google.GData.AccessControl;
using Google.GData.Calendar;
using Google.GData.Client;
using Google.GData.Extensions; 

为了进行回调,您的类必须继承自ICallbackEventHandler接口。

public partial class CalendarEvent : System.Web.UI.Page, ICallbackEventHandler
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                string strRefrence = Page.ClientScript.GetCallbackEventReference(
                    this, 
                    "callArgs", 
                    "ReceiveDateFromServer", 
                    "callContext");

                string strCallBack = "function CallBackToServer(callArgs, callContext) {"
                    + strRefrence + "};";

                Page.ClientScript.RegisterClientScriptBlock(
                    this.GetType(), 
                    "CallBackToServer", 
                    strCallBack, 
                    true);
        }

        private string eventMessage = String.Empty;

        public string GetCallbackResult()
        {
            DateTimeFormatInfo myDTFormatInfo = 
                new CultureInfo("en-US", false).DateTimeFormat;
            DateTime eventStartTime = DateTime.Now;
            
            //Create a CalenderService and authenticate
            CalendarService calService = 
                new CalendarService("GoogleCalendarAndIVRSampleApp");
            
            calService.setUserCredentials("userid@gmail.com", "password");

            string feedUri = 
                "http://www.google.com/calendar/feeds/userid@gmail.com/private/full";
            //Get the Calendar Event you wanted.
            Google.GData.Calendar.EventQuery eventQuery = 
                new Google.GData.Calendar.EventQuery(feedUri);
            //This is the title of your wanted event.
            eventQuery.Query = "NewEvent of mine";
            EventFeed resultEventFeed = calService.Query(eventQuery);

            Google.GData.Calendar.EventEntry myEventEntry = 
                (Google.GData.Calendar.EventEntry)resultEventFeed.Entries[0];
            //If you want to remind the user when the event starts,you can do like this:
            eventStartTime = myEventEntry.Times[0].StartTime;

            //And get the summary of the event.
            eventMessage = myEventEntry.Summary.Text;
            //Of cource,you can get the where,etc.

            return eventStartTime.ToString("F", myDTFormatInfo);
        }

        public void RaiseCallbackEvent(string eventArgument)
        {
            //You can write some useful code here.
        }

        protected void CallUser(object sender, EventArgs e)
        {
            //Call user
            VoicentIVR callUserByIVR = new VoicentIVR("localhost", 1982);
            callUserByIVR.CallText("User's phone", eventMessage, true);
        }
    } 

VoicentIVR类包含在ZIP文件中提供的解决方案中,供下载。

顺便说一下,我的环境是VS2008,但我没有使用.NET Framework 3.5的功能,所以我猜测这些代码在VS2005中也能正常工作。

关注点

IVRGoogle日历Skype

历史

IVR介绍

IVR入门


© . All rights reserved.