Business Mashups Best of the Web APIs


Published on

Published in: Economy & Finance, Technology
1 Comment
No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Business Mashups Best of the Web APIs

    1. 1. Business Mashups: Best of the Web APIs Ron Hess, Jon Jessup, Infopia Charlie Wood, Spanning Partners Track: New AppExchange Developer
    2. 2. Safe Harbor Statement <ul><li>“ Safe harbor” statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements the achievement of which involves risks, uncertainties and assumptions. If any such risks or uncertainties materialize or if any of the assumptions proves incorrect, our results could differ materially from the results expressed or implied by the forward-looking statements we make.  All statements other than statements of historical fact could be deemed forward-looking, including any projections of subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. </li></ul><ul><li>The risks and uncertainties referred to above include - but are not limited to - risks associated with the integration of Sendia Corporation’s technology, operations, infrastructure and personnel with ours; unexpected costs or delays incurred in integrating Sendia with, which could adversely affect our operating results and rate of growth; any unknown errors or limitations in the Sendia technology; any third party intellectual property claims arising from the Sendia technology; customer and partner acceptance and deployment of the AppExchange and AppExchange Mobile platforms; interruptions or delays in our service or our Web hosting; our new business model; breach of our security measures; possible fluctuations in our operating results and rate of growth; the emerging market in which we operate; our relatively limited operating history; our ability to hire, retain and motivate our employees and manage our growth; competition; our ability to continue to release and gain customer acceptance of new and improved versions of our CRM service; unanticipated changes in our effective tax rate; fluctuations in the number of shares outstanding; the price of such shares; foreign currency exchange rates and interest rates. </li></ul><ul><li>Further information on these and other factors that could affect our financial results is included in the reports on Forms 10-K, 10-Q and 8-K and in other filings we make with the Securities and Exchange Commission from time to time, including our Form 10-K for the fiscal year ended January 31, 2006. These documents are available on the SEC Filings section of the Investor Information section of our website at . </li></ul><ul><li>Any unreleased services or features referenced in this or other press releases or public statements are not currently available and may not be delivered on time or at all.  Customers who purchase our services should make purchase decisions based upon features that are currently available., inc. assumes no obligation and does not intend to update these forward-looking statements, except as required by law. </li></ul>
    3. 3. Business Mashups: Best of the Web APIs Track: New AppExchange Developer Jonathan Jessup Development Manager
    4. 4. Infopia Introduction <ul><li>Leader in On-demand eCommerce Solutions </li></ul><ul><li>The industry’s most complete on-demand eCommerce solution suite for online merchants: </li></ul><ul><li>Marketplace Manager ™ </li></ul>INDUSTRY: eCommerce EMPLOYEES: 43 GEOGRAPHY: Global PRODUCTS USED: Oracle On-Demand, Salesforce. # USERS: 350
    5. 5. Multichannel Selling – Means “Multi-Mashup” <ul><li>Infopia utilizes API’s from many partners to deliver a complete ‘Inventory to Cash’ solution </li></ul><ul><li>Real-Time Inventory </li></ul><ul><li>Listings (Price, Promotion, Product, Place) </li></ul><ul><li>Website </li></ul><ul><li>Marketplaces </li></ul><ul><li>Comparison Shopping </li></ul><ul><li>Order Mgmt </li></ul><ul><li>Customer Mgmt </li></ul><ul><li>Fraud Alert </li></ul><ul><li>Online Sales Pipeline </li></ul><ul><li>Marketplaces </li></ul><ul><li>Customers </li></ul><ul><li>Products </li></ul>Market Presence & Shopping Tools Inventory & Merchandising Fulfillment & Service Analysis & Decisions CRM Marketplaces Comparison Shopping ERP Analytics Payment & Shipping
    6. 6. Transforming eCommerce Transactions into Relationships <ul><li>The Challenge – Taking my Business to eBay </li></ul><ul><ul><li>Businesses looking to take advantage of eBay marketplace </li></ul></ul><ul><ul><li>Required resources to making this a viable business channel </li></ul></ul><ul><ul><li>Keeping this channel in sync with their traditional direct sales efforts. </li></ul></ul><ul><li>The Solution –Infopia,, & eBay </li></ul><ul><ul><li>Extend the sales reach to the vast eBay online marketplace in a cost effective manner </li></ul></ul><ul><ul><li>Optimize customer service by maintaining the complete 360-degree customer visibility </li></ul></ul>Ecommerce Solution Marketing Service Sales Analytics Operations & Merchandising Fulfillment & Service Market Presence Analysis/ Decisions CRM Solution Online Sales Channels
    7. 7. Keys to Successful API Integration <ul><li>Language-independent implementation (SOAP XML) </li></ul><ul><li>Accessible over standard Internet protocols (HTTPS) </li></ul><ul><li>Clear and unambiguous description language (WSDL or XSD) </li></ul><ul><li>Full development and sandbox environments </li></ul><ul><li>SDK and sample codes </li></ul><ul><li>Developer’s Network and Support </li></ul>
    8. 8. eBay API Integration <ul><li>API to create, revise and process eBay auctions </li></ul><ul><li>SOAP XML with complete WSDL </li></ul><ul><li>Full development and sandbox environments </li></ul><ul><li>Expansive Developers Network and Support </li></ul><ul><li>eBay API Calls: </li></ul><ul><ul><li>com.ebay.sdk.ApiCall </li></ul></ul><ul><ul><li>com.ebay.soap.eBLBaseComponents.ItemType </li></ul></ul><ul><ul><li>com.ebay.soap.eBLBaseComponents.AddItemRequestType </li></ul></ul><ul><ul><li>com.ebay.soap.eBLBaseComponents.ReviseItemRequestType </li></ul></ul><ul><ul><li>com.ebay.soap.eBLBaseComponents.GetItemTransactionsResponseType </li></ul></ul><ul><ul><li>com.ebay.soap.eBLBaseComponents.AddMemberMessageRTQRequestType </li></ul></ul>
    9. 9. Paypal Integration <ul><li>API to process Paypal Payments </li></ul><ul><li>SOAP XML with complete WSDL and SDK </li></ul><ul><li>Full development and sandbox environments </li></ul><ul><li>Expansive Developers Network and Support </li></ul><ul><li>Paypal API Calls: </li></ul><ul><ul><li> </li></ul></ul><ul><ul><li>com.paypal.soap.api.DoAuthorizationRequestType </li></ul></ul><ul><ul><li>com.paypal.soap.api.DoCaptureRequestType </li></ul></ul><ul><ul><li>com.paypal.soap.api.DoDirectPaymentRequestType </li></ul></ul><ul><ul><li>com.paypal.soap.api.DoExpressCheckoutPaymentRequestType </li></ul></ul>
    10. 10. Google Checkout Integration <ul><li>Google Payment Processing API </li></ul><ul><li>XML Integration with complete XSD and SDK </li></ul><ul><li>Full development and sandbox environments </li></ul><ul><li>Good technical contacts and support </li></ul><ul><li>Google Checkout API Calls: </li></ul><ul><ul><li> </li></ul></ul><ul><ul><li> </li></ul></ul><ul><ul><li> </li></ul></ul>
    11. 11. Infopia Web Services API <ul><li>Allows clients and partners to integrate with Infopia </li></ul><ul><li>SOAP XML, SSL, WSDL, SDK, Code Examples, etc. </li></ul><ul><li>Secure, client-specific access to Marketplace Manager data </li></ul><ul><li>Create, update, retrieve, and synchronize: </li></ul><ul><ul><li>Inventory </li></ul></ul><ul><ul><li>Orders </li></ul></ul><ul><ul><li>Customer data </li></ul></ul>
    12. 12. Infopia Demo
    13. 13. Business Mashups: Best of the Web APIs Track: New AppExchange Developer Charlie Wood Principal [email_address]
    14. 14. The Road to Sync: Feeds and Calendars <ul><li>July ’05: Spanning Salesforce </li></ul><ul><ul><li>RSS/Atom feeds for Salesforce and other AppExchange applications </li></ul></ul><ul><li>July ’06: Spanning Salesforce for iCal </li></ul><ul><ul><li>Web calendars for Salesforce using the iCalendar format and webcal:// protocol </li></ul></ul>
    15. 15. Requirement: Sync with Google Apps <ul><li>Customer Feedback </li></ul><ul><ul><li>Calendar publishing is good </li></ul></ul><ul><ul><li>Two-way sync is better </li></ul></ul><ul><ul><li>Google Apps becoming a viable alternative to Microsoft Exchange </li></ul></ul><ul><li>Technology Challenge </li></ul><ul><ul><li>Differences in protocols, formats, data models </li></ul></ul><ul><ul><li>Transparent operation </li></ul></ul><ul><li>On-demand sync system </li></ul><ul><li>Seamlessly integrates Google Applications with </li></ul><ul><li>Speaks each system’s native language </li></ul>
    16. 16. Spanning Sync for Google and AppExchange <ul><li>How did we address the challenges? </li></ul><ul><ul><li>Created a composite AppExchange application </li></ul></ul><ul><ul><li>Exposed the user interface in a custom tab </li></ul></ul><ul><ul><li>Hosted the sync engine on an external server </li></ul></ul><ul><ul><li>Used the AppExchange SOAP API and PHP Toolkit, and the Google Calendar Data API </li></ul></ul>
    17. 17. User Perspective <ul><li>Salesforce calendar and Google Calendar stay in sync </li></ul><ul><li>Key Requirements </li></ul><ul><ul><li>Simple </li></ul></ul><ul><ul><li>Reliable </li></ul></ul><ul><ul><li>Transparent </li></ul></ul><ul><li>Key Benefits </li></ul><ul><ul><li>Eliminates need to maintain multiple calendars </li></ul></ul><ul><ul><li>Enables calendar sharing with non-SFDC users </li></ul></ul><ul><ul><li>Enables integration with numerous third-party PIM applications </li></ul></ul>
    18. 18. Developer Perspective: Components
    19. 19. Developer Perspective: Process Flow
    20. 20. <ul><li>Login to Google </li></ul><ul><li>Get updated and deleted events </li></ul><ul><li>Create/update events </li></ul><ul><li>Delete events </li></ul>Developer Perspective: The Google Bits
    21. 21. GData: The Google Data API <ul><li>The API for Google Applications </li></ul><ul><ul><li>Google Calendar </li></ul></ul><ul><ul><li>Blogger </li></ul></ul><ul><ul><li>Google Base </li></ul></ul><ul><li>Format </li></ul><ul><ul><li>Atom 1.0 plus custom namespace extensions </li></ul></ul><ul><ul><li>“ Kinds” for specific data types (e.g., calendar events) </li></ul></ul><ul><li>Protocol </li></ul><ul><ul><li>Atom for reading </li></ul></ul><ul><ul><li>Atom Publishing Protocol for writing </li></ul></ul><ul><ul><li>OpenSearch for queries </li></ul></ul><ul><ul><li>Custom authentication for login to Google accounts </li></ul></ul><ul><ul><li>Custom versioning for conflict detection </li></ul></ul>
    22. 22. Login to Google Calendar <ul><li>ClientLogin (for installed apps), not AuthSub (for web apps) </li></ul><ul><li>HTTPS POST login request </li></ul><ul><li>Handle responses from Google: </li></ul><ul><ul><li>success (HTTP 200) </li></ul></ul><ul><ul><li>failure (HTTP 403) </li></ul></ul><ul><ul><li>invalid request </li></ul></ul><ul><ul><li>CAPTCHA challenge </li></ul></ul><ul><li>“ Success” response includes an authentication token, required for all subsequent requests </li></ul>
    23. 23. Get Updated and Deleted Events Using GData <ul><li>Queries are expressed an HTTP URIs: </li></ul><ul><ul><li> </li></ul></ul><ul><li>Queries return an Atom feed with data in elements from two custom XML namespace extensions (“gd” and “gCal”): </li></ul><ul><ul><li>... </li></ul></ul><ul><ul><li><gCal:sendEventNotifications value = &quot;true&quot; /> </li></ul></ul><ul><ul><li><gd:recurrence> DTSTART;VALUE=DATE:20060818 DTEND;VALUE=DATE:20060819 RRULE:FREQ=DAILY;INTERVAL=1;UNTIL=20060823;WKST=SU </gd:recurrence> </li></ul></ul><ul><ul><li><gd:eventStatus value = &quot;; /> </li></ul></ul><ul><ul><li><gd:transparency value = &quot;; /> </li></ul></ul><ul><ul><li><gd:reminder minutes = &quot;10&quot; /> </li></ul></ul><ul><ul><li>... </li></ul></ul><ul><li>Updates and Deletes are returned together, with deletes denoted by their status: </li></ul><ul><ul><li><gd:eventStatus value = &quot;; /> </li></ul></ul>
    24. 24. Create and Update Events Using GData <ul><li>Specify the event using the GData format : </li></ul><ul><ul><li><?xml version=&quot;1.0&quot;?> </li></ul></ul><ul><ul><li><entry xmlns =&quot;; xmlns: openSearch =&quot;; xmlns: gd = &quot;; xmlns: gCal = &quot;; > </li></ul></ul><ul><ul><li>< id> </id> </li></ul></ul><ul><ul><li><category scheme = &quot;; term = &quot;; /> </li></ul></ul><ul><ul><li><title type = &quot;text&quot; > Dreamforce Preparty </title> </li></ul></ul><ul><ul><li><content type = &quot;text&quot; > Don&apos;t stay out too late! </content> </li></ul></ul><ul><ul><li></content> </li></ul></ul><ul><ul><li><gd:transparency value = &quot;; /> </li></ul></ul><ul><ul><li><gd:visibility value = &quot;; /> </li></ul></ul><ul><ul><li><gd:eventStatus value = &quot;; /> </li></ul></ul><ul><ul><li><gd:when startTime = &quot;2006-10-08T21:00:00.000-07:00&quot; endTime = &quot;2006-10-00T00:00:00.000-07:00&quot; > </li></ul></ul><ul><ul><li><gd:reminder minutes = &quot;15&quot; /> </li></ul></ul><ul><ul><li></gd:when> </li></ul></ul><ul><ul><li></entry> </li></ul></ul><ul><li>To create a new event, use HTTP POST to the feed’s URI </li></ul><ul><li>To update an event, use HTTP PUT to the event’s URI </li></ul>
    25. 25. Delete Events Using GData <ul><li>To delete an event, use HTTP DELETE with the event’s URI: </li></ul><ul><li><?php </li></ul><ul><ul><li>$header [] = &quot;Authorization: GoogleLogin auth=&quot; . $this ->authToken; </li></ul></ul><ul><ul><li>$header [] = &quot;X-HTTP-Method-Override: DELETE&quot; ; </li></ul></ul><ul><ul><li>$ch = curl_init (); </li></ul></ul><ul><ul><li>curl_setopt ( $ch , CURLOPT_HTTPHEADER, $header ); </li></ul></ul><ul><ul><li>curl_setopt ( $ch , CURLOPT_URL, $theEventURI . &quot;?gsessionid=&quot; . $this ->sessionID); </li></ul></ul><ul><ul><li>curl_setopt ( $ch , CURLOPT_HEADER, 1 ); </li></ul></ul><ul><ul><li>curl_setopt ( $ch , CURLOPT_RETURNTRANSFER, 1 ); </li></ul></ul><ul><ul><li>curl_setopt ( $ch , CURLOPT_POST, 1 ); </li></ul></ul><ul><ul><li>$tmp = curl_exec ( $ch ); </li></ul></ul><ul><ul><li>curl_close ( $ch ); </li></ul></ul><ul><ul><li>?> </li></ul></ul>
    26. 26. GData Optimistic Concurrency (Versioning) <ul><li>Motivation </li></ul><ul><ul><li>To prevent one client from overwriting another’s changes </li></ul></ul><ul><li>Implementation </li></ul><ul><ul><li>A version ID is appended to every GData entry’s URI: </li></ul></ul><ul><ul><ul><li> 63293840053 </li></ul></ul></ul><ul><ul><li>When a PUT or DELETE is performed, the version in the request is compared to the version of the existing entry </li></ul></ul><ul><ul><li>If the versions don’t match, Google responds with HTTP 409 Conflict </li></ul></ul><ul><li>Beta </li></ul><ul><ul><li>This is still a work in progress </li></ul></ul>
    27. 27. Lessons Learned <ul><li>Developing for GData feels like developing for AppExchange </li></ul><ul><ul><li>No software to install, no biz dev meetings to attend </li></ul></ul><ul><ul><li>Develop using your language and tools of choice </li></ul></ul><ul><li>Google Calendar Data API is still in beta </li></ul><ul><ul><li>Only some data types supported (e.g., no contacts or tasks) </li></ul></ul><ul><ul><li>“ Optimistic concurrency” versioning system still in development </li></ul></ul><ul><ul><li>Format and protocol docs don’t yet always match behavior </li></ul></ul><ul><ul><li>No scripting-level toolkits available yet, so you’ll be writing Java, C#, or raw HTTP requests </li></ul></ul><ul><li>AppExchange + Google mashups can be incredibly powerful and relatively simple to create </li></ul>
    28. 28. For More Information <ul><li>Google Data APIs (Beta) Developer’s Guide </li></ul><ul><ul><li> </li></ul></ul><ul><li>Using the Google Calendar Data API </li></ul><ul><ul><li> </li></ul></ul><ul><li>Google Account Authentication </li></ul><ul><ul><li> </li></ul></ul><ul><li>Google Groups: Google Calendar Data API </li></ul><ul><ul><li> </li></ul></ul><ul><li>Moonwatcher (My Blog) </li></ul><ul><ul><li> </li></ul></ul>
    29. 29. Ron Hess Charlie Wood Principal Jonathan Jessup QUESTION & ANSWER SESSION Spanning Partners Jonathan Jessup Development Manager Developer Marketing
    30. 30. Session Feedback Let us know how we’re doing! <ul><li>Please score the session from 5 to 1 (5=excellent,1=needs improvement) on the following categories: </li></ul><ul><ul><li>Overall rating of the session </li></ul></ul><ul><ul><li>Quality of content </li></ul></ul><ul><ul><li>Strength of presentation delivery </li></ul></ul><ul><ul><li>Relevance of the session to your organization </li></ul></ul>Save time! Use your cell phone or mobile device to send Feedback via SMS/Text Messaging! Send a message to 26335 In the message body: Session 234, #### For example, “ Session 123, 5555 ” Session ID: 234 Session ID # Scores for 4 categories SMS Voting powered by:
    31. 31. Login Sample Code (Part 1 of 3) <ul><ul><li><?php </li></ul></ul><ul><ul><li>function authenticate($gcUname, $gcPword, $loginToken, $loginCaptcha) { </li></ul></ul><ul><ul><li>$header[] = &quot;Content-type: application/x-www-form-urlencoded&quot;; </li></ul></ul><ul><ul><li>$postFields = &quot;AccountType=HOSTED_OR_GOOGLE&Email=&quot;.urlencode($gcUname).&quot;&Passwd=&quot;; </li></ul></ul><ul><ul><li>$postFields .= urlencode($gcPword).&quot;&source=Spanning-AppExSync-1&service=cl&quot;; </li></ul></ul><ul><ul><li>if(strlen($loginToken) && strlen($loginCaptcha)) { </li></ul></ul><ul><ul><li>$postFields .= &quot;&logintoken=&quot;.$loginToken.&quot;&logincaptcha=&quot;.$loginCaptcha; </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>$ch = curl_init(&quot;;); </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_HTTPHEADER, $header); </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_HEADER, 1); // include the header in the output </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // store the output in a variable </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_POST, 1); </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields); </li></ul></ul><ul><ul><li>$tmp = curl_exec($ch); </li></ul></ul><ul><ul><li>curl_close($ch); </li></ul></ul><ul><ul><li>// parse the response and check for authentication success/failure </li></ul></ul><ul><ul><li>$theResponse = $this->parse_response($tmp); </li></ul></ul><ul><ul><li>switch($theResponse[&quot;code&quot;]) { </li></ul></ul><ul><ul><li>case &quot;200&quot;: // success </li></ul></ul><ul><ul><li>break; </li></ul></ul><ul><ul><li>case &quot;403&quot;: </li></ul></ul><ul><ul><li>$this->handleBadLoginResponse($theResponse[&quot;body&quot;]); </li></ul></ul><ul><ul><li>break; </li></ul></ul><ul><ul><li>default: </li></ul></ul><ul><ul><li>$msg = &quot;Unrecognized response status code on attempted Google Calendar authentication. &quot;; </li></ul></ul><ul><ul><li>$msg .= &quot;Status code: &quot;.$theResponse[&quot;code&quot;].&quot; &quot;; </li></ul></ul><ul><ul><li>$msg .= &quot;Body: &quot;.$theResponse[&quot;body&quot;].&quot; &quot;; </li></ul></ul><ul><ul><li>failWithError($msg); </li></ul></ul><ul><ul><li>} </li></ul></ul>
    32. 32. Login Sample Code (Part 2 of 3) <ul><ul><li>// extract authorization token </li></ul></ul><ul><ul><li>$ret = $theResponse[&quot;body&quot;]; </li></ul></ul><ul><ul><li>if(ereg(&quot;Auth=(.*) &quot;,$ret,$regs)) { </li></ul></ul><ul><ul><li>$this->authToken = $regs[1]; // authenticaion token </li></ul></ul><ul><ul><li>} else { </li></ul></ul><ul><ul><li>failWithError(&quot;Authorization token not found in response from Google Calendar. &quot;); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>// make subsequent (authenticated) request to Calendar </li></ul></ul><ul><ul><li>$ch = curl_init(&quot;;); </li></ul></ul><ul><ul><li>unset($header); </li></ul></ul><ul><ul><li>$header[] = &quot;Authorization: GoogleLogin auth=&quot;.$this->authToken; </li></ul></ul><ul><ul><li>$header[] = &quot;Content-type: application/atom+xml&quot;; </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_HTTPHEADER, $header); </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_HEADER, 1); // include the header in the output </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // store the output in a variable </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_POST, 1); </li></ul></ul><ul><ul><li>curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); // DON'T follow the (expected) redirect </li></ul></ul><ul><ul><li>$tmp = curl_exec($ch); </li></ul></ul><ul><ul><li>curl_close($ch); </li></ul></ul><ul><ul><li>// parse the response and check for authentication success/failure </li></ul></ul><ul><ul><li>$theResponse = $this->parse_response($tmp); </li></ul></ul><ul><ul><li>switch($theResponse[&quot;code&quot;]) { </li></ul></ul><ul><ul><li>case &quot;302&quot;: // success </li></ul></ul><ul><ul><li>break; </li></ul></ul><ul><ul><li>default: </li></ul></ul><ul><ul><li>$msg = &quot;Unrecognized response status code (not 302) on authenticated request to Google Calendar. &quot;; </li></ul></ul><ul><ul><li>$msg .= &quot;Status code: &quot;.$theResponse[&quot;code&quot;].&quot; &quot;; </li></ul></ul><ul><ul><li>$msg .= &quot;Body: &quot;.$theResponse[&quot;body&quot;].&quot; &quot;; </li></ul></ul><ul><ul><li>failWithError($msg); </li></ul></ul><ul><ul><li>} </li></ul></ul>
    33. 33. Login Sample Code (Part 3 of 3) <ul><ul><li>// extract session id </li></ul></ul><ul><ul><li>$ret = $theResponse[&quot;header&quot;][&quot;Location&quot;]; </li></ul></ul><ul><ul><li>if(ereg(&quot;([^?]*).*gsessionid=(.*) &quot;,$ret,$regs)) { </li></ul></ul><ul><ul><li>$this->sessionID = $regs[2]; // authentication token </li></ul></ul><ul><ul><li>$this->feedURL = $regs[1]; // feed URL </li></ul></ul><ul><ul><li>} else { </li></ul></ul><ul><ul><li>failWithError(&quot;Session ID not found in response from Google Calendar.&quot;); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>debug(&quot;Connected to Google and authenticated.&quot;); </li></ul></ul><ul><ul><li>} </li></ul></ul><ul><ul><li>?> </li></ul></ul>