This site contains the documentation that is relevant to older WSO2 product versions and offerings.
For the latest WSO2 documentation, visit https://wso2.com/documentation/.

Deal Completion in Hubspot

The third use case in the Hubspot business scenario is deal completion. This page describes the relevant tasks and the operations you use in the Hubspot connector and the other ESB connectors. It contains the following sections:

Overview 

The flow for deal completion is illustrated in the following diagram. The ESB connectors for Billiving, TSheets, and ActiveCampaign will be used to connect to each service.

Retrieving deals, creating clients, creating projects and updating deal stages

  1. Retrieve deals which are in the "Won" stage from the Hubspot API using the getRecentlyModifiedDeals operation.
  2. Check if the Billiving client ID exists in the Hubspot API using the getContactById operation.
  3. Check if the client already exists in the Billiving API using the listClients operation.
  4. If the client does not exist, create the client in the Billiving API using the createClient operation.
  5. Update the Billiving client ID if it does not exist in the Hubspot API using the updateContact operation.
  6. Create a project (deal) in the TSheets API using the addJobCodes operation. The parent job code will be the client, which can have multiple child job codes as deals. These deals will have time entries.
  7. If a new job code is created, update the Hubspot deal with the job code ID using the updateDeal operation in the Hubspot API.
  8. Update the deal stage as "Won" in the ActiveCampaign API using the updateDeal operation.
Hubspot operations
Billiving operations
TSheets operations
ActiveCampaign operations

Prerequisites

  1. Create custom properties for deals as follows in the Hubspot API:
    1. 'TSheet Job Code' with the field type 'Single-line text'.
    2. 'Hourly Rate' with the field type 'Single-line text'.
  2. Create custom properties for contacts as follows in the Hubspot API:
    1. 'TSheets Job Code' with the field type 'Single-line text'.
    2. 'Biliving Client ID' with the field type 'Single-line text'    
Samples
Sample Proxy for retrieving deals which are in the “Won” stage from Hubspot, creating the client in Billiving if they do not exist, creating a project (deal) in TSheets and the deal stage as “Won” in ActiveCampaign
<?xml version="1.0" encoding="UTF-8"?>
<!--
   Copyright (c) 2005-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
   WSO2 Inc. licenses this file to you under the Apache License,
   Version 2.0 (the "License"); you may not use this file except
   in compliance with the License.
   You may obtain a copy of the License at
   http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied. See the License for the
   specific language governing permissions and limitations
   under the License.
-->
<!--
   Retrieve deals which are in "Won" stage from the Hubspot API and;
   Create the client in the Billiving API, if they do not exist.
   Create a project (deal) in the TSheets API (The parent job code will be the client, which can have multiple child job
   codes as deals. These deals will have time entries.).
   Update the deal stage as "Won" in the ActiveCampaign API.
-->
<proxy xmlns="http://ws.apache.org/ns/synapse" name="hubSpot_createContactsAndProjectsForWonDeals" transports="https http"
   startOnLoad="true" trace="disable">
   <target>
      <inSequence>
         <!--Hubspot Properties -->
         <property name="hubspot.apiUrl" value="https://api.hubapi.com" />
         <property name="hubspot.apiKey" expression="json-eval($.hubSpot.apiKey)" />
         <!--ActiveCampaign Properties -->
         <property name="activecampaign.apiUrl" expression="json-eval($.activeCampaign.apiUrl)" />
         <property name="activecampaign.apiKey" expression="json-eval($.activeCampaign.apiKey)" />
         <!-- Billiving -->
         <property name="billiving.apiUrl" value="https://www.billiving.com" />
         <property name="billiving.accessToken" expression="json-eval($.billiving.accessToken)" />
         <!-- Tsheets -->
         <property name="tsheets.apiUrl" expression="json-eval($.tSheets.apiUrl)" />
         <property name="tsheets.accessToken" expression="json-eval($.tSheets.accessToken)" />
         <!--Common Properties -->
         <property name="responseString" value="" scope="operation" />
         <!-- Hubspot Get Recently Modified Deals '/deals/v1/deal/recent/modified' -->
         <hubspot.init>
            <apiKey>{$ctx:hubspot.apiKey}</apiKey>
            <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
         </hubspot.init>
         <hubspot.getRecentlyModifiedDeals>
         </hubspot.getRecentlyModifiedDeals>
         <header name="Content-Encoding" action="remove" scope="transport" />
         <property name="wonDealsCount" expression="count(//results/properties/dealstage/value[text() = 'closedwon'])"
            scope="operation" />
         <property name="wonDealIndex" value="0" scope="operation" />
         <property name="dealsCount" expression="count(//results)" scope="operation" />
         <property name="dealIndex" value="0" scope="operation" />
         <filter xpath="get-property('operation','wonDealsCount') = 0">
            <then>
               <property name="id" value="{}" />
               <call-template target="responseHandlerTemplate">
                  <with-param name="id" value="{$ctx:id}" />
                  <with-param name="activity" value="hubSpot_retrieveWonDeals" />
                  <with-param name="status" value="skipped" />
                  <with-param name="message" value="Couldn't find new won deals to be processed." />
               </call-template>
               <loopback />
            </then>
            <else>
               <!--FOR EACH Estimates : BEGIN -->
               <iterate continueParent="true" id="deals" expression="//results" sequential="true">
                  <target>
                     <sequence>
                        <property name="hubspot.dealId" expression="//results/dealId" />
                        <property name="hubspot.dealstatus" expression="//results/properties/dealstage/value" />
                        <property name="hubspot.activeCampaignId" expression="//results/properties/active_campaign_id/value" />

                        <filter xpath="get-property('hubspot.dealstatus') = 'closedwon' ">
                           <then>
                              <property name="hubspot.companyId" expression="//results/associations/associatedCompanyIds" />
                              <property name="hubspot.contactId" expression="json-eval($.results.associations.associatedVids)" />
                              <property name="hubspot.dealName" expression="//results/properties/dealname/value" />
                              <property name="hubspot.tsheetsJobCode" expression="json-eval($.results.properties.tsheet_job_code.value)" />
                              <property name="hubspot.hourlyRate" expression="json-eval($.results.properties.hourly_rate.value)" />
                              <filter
                                 xpath="(get-property('hubspot.tsheetsJobCode') = 'null') or (get-property('hubspot.tsheetsJobCode') ='' )">
                                 <then>
                                    <!-- START : If activecampaign deal update deal status -->
                                    <filter source="boolean(get-property('hubspot.activeCampaignId'))" regex="true">
                                       <then>
                                          <property name="dealIdObject"
                                             expression="fn:concat('hubSpot_dealId:',get-property('hubspot.dealId'),',activeCampaign_dealId:',get-property('hubspot.activeCampaignId'))" />
                                          <header name="Content-Encoding" action="remove" scope="transport" />
                                          <!-- Workaround to eliminate the Host header issue in ActiveCampaign. -->
                                          <property name="Host" value="host.wso2.com" scope="transport" />
                                          <activecampaign.init>
                                             <apiUrl>{$ctx:activecampaign.apiUrl}</apiUrl>
                                             <apiKey>{$ctx:activecampaign.apiKey}</apiKey>
                                             <apiOutput>json</apiOutput>
                                          </activecampaign.init>
                                          <activecampaign.updateDeal>
                                             <dealId>{$ctx:hubspot.activeCampaignId}</dealId>
                                             <status>1</status>
                                          </activecampaign.updateDeal>
                                          <header name="Content-Encoding" action="remove" scope="transport" />
                                          <property name="activecampaign.requestStatus" expression="json-eval($.success)" />
                                          <filter source="get-property('activecampaign.requestStatus')" regex="1">
                                             <then>
                                                <property name="status" value="success" />
                                                <property name="message" value="Deal has been successfully updated." />
                                             </then>
                                             <else>
                                                <property name="status" value="error" />
                                                <property name="message" expression="json-eval($.)" />
                                             </else>
                                          </filter>
                                          <call-template target="responseHandlerTemplate">
                                             <with-param name="id" value="{$ctx:dealIdObject}" />
                                             <with-param name="activity" value="activeCampaign_updateDealStatus" />
                                             <with-param name="status" value="{$ctx:status}" />
                                             <with-param name="message" value="{$ctx:message}" />
                                          </call-template>
                                       </then>
                                    </filter>
                                    <!-- END : If activecampaign deal update deal status -->
                                    <!-- START : Create Biliving Client And Organization -->
                                    <!-- Hubspot Get Contact By Id '/contacts/v1/contact/vid/:contact_id/profile' -->
                                    <hubspot.init>
                                       <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                       <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                    </hubspot.init>
                                    <hubspot.getContactById>
                                       <contactId>{$ctx:hubspot.contactId}</contactId>
                                    </hubspot.getContactById>
                                    <header name="Content-Encoding" action="remove" scope="transport" />
                                    <property name="hubspot.contactEmail" expression="json-eval($.properties.email.value)" />
                                    <property name="hubspot.contactFirstName" expression="json-eval($.properties.firstname.value)" />
                                    <property name="hubspot.contactLastName" expression="json-eval($.properties.lastname.value)" />
                                    <property name="hubspot.contactFullName"
                                       expression="fn:concat(get-property('hubspot.contactFirstName'),' ',get-property('hubspot.contactLastName'))" />
                                    <property name="hubspot.contactJobCode" expression="json-eval($.properties.tsheets_job_code.value)" />
                                    <property name="billiving.contactId" expression="json-eval($.properties.biliving_client_id.value)" />
                                    <property name="hubspot.companyName" expression="json-eval($.associated-company.properties.name.value)" />
                                    <property name="hubspot.companyWebsite" expression="json-eval($.associated-company.properties.website.value)" />
                                    <property name="hubspot.companyPhone" expression="json-eval($.associated-company.properties.phone.value)" />
                                    <property name="hubspot.companyAddress" expression="json-eval($.associated-company.properties.address.value)" />
                                    <property name="hubspot.companyCity" expression="json-eval($.associated-company.properties.city.value)" />
                                    <property name="hubspot.companyZip" expression="json-eval($.associated-company.properties.zip.value)" />
                                    <!-- Check billiving client ID exist in Hubspot. -->
                                    <filter
                                       xpath="(get-property('billiving.contactId') = 'null') or (get-property('billiving.contactId') ='' )">
                                       <then>
                                          <property name="billiving.hasContact" action="remove" />
                                          <!-- Check contact is already in billiving -->
                                          <billiving.init>
                                             <apiUrl>{$ctx:billiving.apiUrl}</apiUrl>
                                             <accessToken>{$ctx:billiving.accessToken}</accessToken>
                                          </billiving.init>
                                          <billiving.listClients>
                                             <freeText>{$ctx:hubspot.contactEmail}</freeText>
                                          </billiving.listClients>
                                          <header name="Content-Encoding" action="remove" scope="transport" />
                                          <script language="js">
                                             <![CDATA[
                                                var payload = mc.getPayloadJSON();
                                                if(payload.length > 0){
                                                   mc.setProperty('billiving.hasContact', true);
                                                   mc.setProperty('billiving.contactId', payload[0].Id);
                                                }                              
                                             ]]>
                                          </script>
                                          <!-- START : Create Billiving client is not exist. -->
                                          <filter source="boolean(get-property('billiving.hasContact'))" regex="false">
                                             <then>
                                                <property name="uri.var.id" action="remove" />
                                                <billiving.init>
                                                   <apiUrl>{$ctx:billiving.apiUrl}</apiUrl>
                                                   <accessToken>{$ctx:billiving.accessToken}</accessToken>
                                                </billiving.init>
                                                <billiving.createClient>
                                                   <organizationName>{$ctx:hubspot.companyName}</organizationName>
                                                   <website>{$ctx:hubspot.companyWebsite}</website>
                                                   <email>{$ctx:hubspot.contactEmail}</email>
                                                   <contactName>{$ctx:hubspot.contactFullName}</contactName>
                                                   <telephone1>{$ctx:hubspot.companyPhone}</telephone1>
                                                   <address1>{$ctx:hubspot.companyAddress}</address1>
                                                   <city>{$ctx:hubspot.companyCity}</city>
                                                   <zipCode>{$ctx:hubspot.companyZip}</zipCode>
                                                </billiving.createClient>
                                                <header name="Content-Encoding" action="remove" scope="transport" />
                                                <filter source="$axis2:HTTP_SC" regex="200">
                                                   <then>
                                                      <property name="billiving.contactId" expression="json-eval($.Id)" />
                                                      <property name="contactIdObject"
                                                         expression="fn:concat('hubSpot_contactId:',get-property('hubspot.contactId'),',billiving_contactId:',get-property('billiving.contactId'))" />
                                                      <property name="status" value="success" />
                                                      <property name="message" value="Contact has been successfully created." />
                                                   </then>
                                                   <else>
                                                      <property name="contactIdObject"
                                                         expression="fn:concat('hubSpot_contactId:',get-property('hubspot.contactId'))" />
                                                      <property name="status" value="error" />
                                                      <property name="message" expression="json-eval($.)" />
                                                   </else>
                                                </filter>
                                                <call-template target="responseHandlerTemplate">
                                                   <with-param name="id" value="{$ctx:contactIdObject}" />
                                                   <with-param name="activity" value="billiving_createContact" />
                                                   <with-param name="status" value="{$ctx:status}" />
                                                   <with-param name="message" value="{$ctx:message}" />
                                                </call-template>
                                             </then>
                                          </filter>
                                          <!-- Update billiving client ID if not exsist in hubspot. -->
                                          <filter source="boolean(get-property('billiving.contactId'))" regex="true">
                                             <then>
                                                <payloadFactory media-type="json">
                                                   <format>
                                                      {
                                                      "properties": [
                                                      {
                                                      "property": "biliving_client_id",
                                                      "value":
                                                      "$1"
                                                      }
                                                      ]
                                                      }
                                                   </format>
                                                   <args>
                                                      <arg expression="get-property('billiving.contactId')" />
                                                   </args>
                                                </payloadFactory>
                                                <property name="hubspot.properties" expression="json-eval($.properties)" />
                                                <hubspot.init>
                                                   <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                                   <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                                </hubspot.init>
                                                <hubspot.updateContact>
                                                   <properties>{$ctx:hubspot.properties}</properties>
                                                   <contactId>{$ctx:hubspot.contactId}</contactId>
                                                </hubspot.updateContact>
                                                <!-- Do a dummy get -->
                                                <hubspot.init>
                                                   <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                                   <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                                </hubspot.init>
                                                <hubspot.getContactById>
                                                   <contactId>{$ctx:hubspot.contactId}</contactId>
                                                </hubspot.getContactById>
                                             </then>
                                          </filter>
                                       </then>
                                    </filter>
                                    <!-- Check Tsheet Contact JobCode is not being created and billiving client is exists,
                                       if not create -->
                                    <filter
                                       xpath="(((get-property('hubspot.contactJobCode') = 'null') or (get-property('hubspot.contactJobCode') ='' )) and ((get-property('billiving.contactId') != 'null') and (get-property('billiving.contactId') !='' )))">
                                       <then>
                                          <payloadFactory media-type="json">
                                             <format>
                                                [
                                                {
                                                "name":"$1",
                                                "short_code":"$2"
                                                }
                                                ]
                                             </format>
                                             <args>
                                                <arg expression="get-property('hubspot.contactFullName')" />
                                                <arg expression="get-property('billiving.contactId')" />
                                             </args>
                                          </payloadFactory>
                                          <property name="tsheets.jobcodeObj" expression="json-eval($.)" />
                                          <tsheets.init>
                                             <accessToken>{$ctx:tsheets.accessToken}</accessToken>
                                             <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
                                          </tsheets.init>
                                          <tsheets.addJobCodes>
                                             <jobCodes>{$ctx:tsheets.jobcodeObj}</jobCodes>
                                          </tsheets.addJobCodes>
                                          <property name="tsheets.statusCode" expression="json-eval($.results.jobcodes.1._status_code)" />
                                          <switch source="get-property('tsheets.statusCode')">
                                             <case regex="200">
                                                <property name="tsheets.jobCodeId" expression="json-eval($.results.jobcodes.1.id)" />
                                                <property name="hubspot.contactJobCode" expression="get-property('tsheets.jobCodeId')" />
                                                <property name="jobCodeIdObject"
                                                   expression="fn:concat('hubSpot_contactId:',get-property('hubspot.contactId'),',tSheets_jobCodeId:',get-property('tsheets.jobCodeId'))" />
                                                <property name="message" value="Job code has been successfully created." />
                                                <property name="status" value="success" />
                                             </case>
                                             <case regex="417">
                                                <property name="jobCodeIdObject"
                                                   expression="fn:concat('hubSpot_contactId:',get-property('hubspot.contactId'))" />
                                                <property name="status" value="error" />
                                                <property name="message" expression="json-eval($.)" />
                                             </case>
                                          </switch>
                                          <call-template target="responseHandlerTemplate">
                                             <with-param name="id" value="{$ctx:jobCodeIdObject}" />
                                             <with-param name="activity" value="tSheets_createJobCodeForContact" />
                                             <with-param name="status" value="{$ctx:status}" />
                                             <with-param name="message" value="{$ctx:message}" />
                                          </call-template>
                                          <!-- If new Jobcode is created update hubspot contact with jobcode id -->
                                          <filter xpath="get-property('tsheets.statusCode') = 200 ">
                                             <then>
                                                <payloadFactory media-type="json">
                                                   <format>
                                                      {
                                                      "properties": [
                                                      {
                                                      "property": "tsheets_job_code",
                                                      "value": "$1"
                                                      }
                                                      ]
                                                      }
                                                   </format>
                                                   <args>
                                                      <arg expression="get-property('tsheets.jobCodeId')" />
                                                   </args>
                                                </payloadFactory>
                                                <property name="hubspot.properties" expression="json-eval($.properties)" />
                                                <hubspot.init>
                                                   <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                                   <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                                </hubspot.init>
                                                <hubspot.updateContact>
                                                   <properties>{$ctx:hubspot.properties}</properties>
                                                   <contactId>{$ctx:hubspot.contactId}</contactId>
                                                </hubspot.updateContact>
                                                <!-- Do a dummy get -->
                                                <hubspot.init>
                                                   <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                                   <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                                </hubspot.init>
                                                <hubspot.getContactById>
                                                   <contactId>{$ctx:hubspot.contactId}</contactId>
                                                </hubspot.getContactById>
                                             </then>
                                          </filter>
                                       </then>
                                    </filter>
                                    <!-- If Parent job code is there -->
                                    <filter
                                       xpath="(get-property('hubspot.contactJobCode') != 'null') or (get-property('hubspot.contactJobCode') !='' )">
                                       <then>
                                          <payloadFactory media-type="json">
                                             <format>
                                                [
                                                {
                                                "name":"$1",
                                                "short_code":"$2",
                                                "parent_id":"$3",
                                                "billable":"yes",
                                                "assigned_to_all":"yes",
                                                "billable_rate":"$4"
                                                }
                                                ]
                                             </format>
                                             <args>
                                                <arg expression="get-property('hubspot.dealName')" />
                                                <arg expression="get-property('hubspot.dealId')" />
                                                <arg expression="get-property('hubspot.contactJobCode')" />
                                                <arg expression="get-property('hubspot.hourlyRate')" />
                                             </args>
                                          </payloadFactory>
                                          <property name="tsheets.jobcodeObj" expression="json-eval($.)" />
                                          <tsheets.init>
                                             <accessToken>{$ctx:tsheets.accessToken}</accessToken>
                                             <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
                                          </tsheets.init>
                                          <tsheets.addJobCodes>
                                             <jobCodes>{$ctx:tsheets.jobcodeObj}</jobCodes>
                                          </tsheets.addJobCodes>
                                          <property name="tsheets.statusCode" expression="json-eval($.results.jobcodes.1._status_code)" />
                                          <switch source="get-property('tsheets.statusCode')">
                                             <case regex="200">
                                                <property name="tsheets.jobCodeId" expression="json-eval($.results.jobcodes.1.id)" />
                                                <property name="jobCodeIdObject"
                                                   expression="fn:concat('hubSpot_dealId:',get-property('hubspot.dealId'),',tSheets_jobCodeId:',get-property('tsheets.jobCodeId'))" />
                                                <property name="message" value="Job code has been successfully created." />
                                                <property name="status" value="success" />
                                             </case>
                                             <case regex="417">
                                                <property name="jobCodeIdObject"
                                                   expression="fn:concat('hubSpot_dealId:',get-property('hubspot.dealId'))" />
                                                <property name="status" value="error" />
                                                <property name="message" expression="json-eval($.)" />
                                             </case>
                                          </switch>
                                          <call-template target="responseHandlerTemplate">
                                             <with-param name="id" value="{$ctx:jobCodeIdObject}" />
                                             <with-param name="activity" value="tSheets_createJobCodeForDeal" />
                                             <with-param name="status" value="{$ctx:status}" />
                                             <with-param name="message" value="{$ctx:message}" />
                                          </call-template>
                                          <!-- If new Jobcode is created update hubspot deal with jobcode id -->
                                          <filter
                                             xpath="(get-property('tsheets.statusCode') = 200) or (get-property('tsheets.statusCode') = 202) ">
                                             <then>
                                                <payloadFactory media-type="json">
                                                   <format>
                                                      {
                                                      "properties": [
                                                      {
                                                      "name": "tsheet_job_code",
                                                      "value": "$1"
                                                      }
                                                      ]
                                                      }
                                                   </format>
                                                   <args>
                                                      <arg expression="get-property('tsheets.jobCodeId')" />
                                                   </args>
                                                </payloadFactory>
                                                <property name="hubspot.properties" expression="json-eval($.properties)" />
                                                <hubspot.init>
                                                   <apiKey>{$ctx:hubspot.apiKey}</apiKey>
                                                   <apiUrl>{$ctx:hubspot.apiUrl}</apiUrl>
                                                </hubspot.init>
                                                <hubspot.updateDeal>
                                                   <dealId>{$ctx:hubspot.dealId}</dealId>
                                                   <properties>{$ctx:hubspot.properties}</properties>
                                                </hubspot.updateDeal>
                                             </then>
                                          </filter>
                                       </then>
                                    </filter>
                                 </then>
                              </filter>
                           </then>
                        </filter>
                        <property name="dealIndex" expression="get-property('operation','dealIndex') + 1"
                           scope="operation" />
                        <filter xpath="get-property('operation','dealsCount') = get-property('operation','dealIndex') ">
                           <then>
                              <loopback />
                           </then>
                        </filter>
                     </sequence>
                  </target>
               </iterate>
            </else>
         </filter>
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" />
         <filter source="boolean(get-property('operation', 'responseString'))" regex="false">
            <then>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response": {
                     "process": "hubSpot_createContactsAndProjectsForWonDeals",
                     "activityResponse": [
                     {
                     "activity":"hubSpot_retrieveWonDeals",
                     "status": "skipped",
                     "message": "Couldn't find new won deals to be process."
                     }
                     ]
                     }
                     }
                  </format>
               </payloadFactory>
            </then>
            <else>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response":
                     {
                     "process":"hubSpot_createContactsAndProjectsForWonDeals",
                     "activityResponse":[$1]
                     }
                     }
                  </format>
                  <args>
                     <arg expression="get-property('operation', 'responseString')" />
                  </args>
               </payloadFactory>
            </else>
         </filter>
         <send />
      </outSequence>
   </target>
   <description />
</proxy>
Sample Request for retrieving deals which are in the “Won” stage from Hubspot, creating the client in Billiving if they do not exist, creating a project (deal) in TSheets and the deal stage as “Won” in ActiveCampaign
{
	"hubSpot":{
		"apiKey":"982855ac-b43b-4c89-833b-eb9002379825"
	},
	"activeCampaign":{
		"apiUrl":"http://asoft.activehosted.com",
		"apiKey":"190c775d3efbf7b2928365a5e822c601285b329564fc19a03e6a63e73105fab895944529"
	},
	"billiving":{
		"accessToken":"0b635066-0329-43a9-9f30-7ead387c45cb"
	},
	"tSheets":{
		"apiUrl":"https://malivera.tsheets.com",
		"accessToken":"S.2__96eb91af9a07d31d12f8f2f79a4249f9c85bc9d6"
	}
}

Retrieving time entries and creating invoices

  1. Retrieve clients from the Billiving API using the listClients operation.
  2. Retrieve job codes from the TSheets API using the listJobCodes operation.
  3. Retrieve the time entries for a particular time period given in the request from the TSheets API using the listTimeSheets operation and create an invoice in the Billiving API using the createInvoice operation.
Billiving operations
TSheets operations
Samples
Sample Proxy for retrieving time entries for a particular period from TSheets and creating an invoice in Billiving for book keeping purposes
<?xml version="1.0" encoding="UTF-8"?>
<!--
   Copyright (c) 2005-2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
   WSO2 Inc. licenses this file to you under the Apache License,
   Version 2.0 (the "License"); you may not use this file except
   in compliance with the License.
   You may obtain a copy of the License at
   http://www.apache.org/licenses/LICENSE-2.0
   Unless required by applicable law or agreed to in writing,
   software distributed under the License is distributed on an
   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   KIND, either express or implied. See the License for the
   specific language governing permissions and limitations
   under the License.
-->
<!-- Retrieve time entries for a requested period from the TSheets API and create invoices in the Billiving API for book 
   keeping purposes. -->
<proxy xmlns="http://ws.apache.org/ns/synapse" name="hubSpot_createInvoicesForTimeEntries" transports="https http"
   startOnLoad="true" trace="disable">
   <target>
      <inSequence>
         <!--Hubspot Properties -->
         <property name="hubspot.apiUrl" value="https://api.hubapi.com" />
         <property name="hubspot.apiKey" expression="json-eval($.hubSpot.apiKey)" />
         <!-- Billiving -->
         <property name="billiving.apiUrl" value="https://www.billiving.com" />
         <property name="billiving.accessToken" expression="json-eval($.billiving.accessToken)" />
         <!-- Tsheets -->
         <property name="tsheets.apiUrl" expression="json-eval($.tSheets.apiUrl)" />
         <property name="tsheets.accessToken" expression="json-eval($.tSheets.accessToken)" />
         <property name="tsheets.timeSheetStartDate" expression="json-eval($.tSheets.startDate)" />
         <property name="tsheets.timeSheetEndDate" expression="json-eval($.tSheets.endDate)" />
         <!--Common Properties -->
         <property name="responseString" value="" scope="operation" />
         <!-- List Billiving clients -->
         <billiving.init>
            <apiUrl>{$ctx:billiving.apiUrl}</apiUrl>
            <accessToken>{$ctx:billiving.accessToken}</accessToken>
         </billiving.init>
         <billiving.listClients>
         </billiving.listClients>
         <property name="billiving.clients" expression="json-eval($.)" />
         <header name="Content-Encoding" action="remove" scope="transport" />
         <!-- List Tsheets jobcodes and create array of jobcodes which has child jobcodes and shortcode -->
         <tsheets.init>
            <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
            <accessToken>{$ctx:tsheets.accessToken}</accessToken>
         </tsheets.init>
         <tsheets.listJobCodes>
            <parentIds>0</parentIds>
         </tsheets.listJobCodes>
         <!-- Filter and create jobCode list which has mapping with Billiving clients. -->
         <script language="js">
            <![CDATA[
               var payload = mc.getPayloadJSON();
               var clients = eval("(" + mc.getProperty('billiving.clients') + ")");
               var _jobCodes = payload.results.jobcodes;
               var jobCodes = [];
               for(var i = 0; i < clients.length ; i++){
                  var clientId = clients[i].Id;
                  for(var key in _jobCodes){
                     var _jobCodeObject = _jobCodes[key];
                     var shortCode = _jobCodeObject.short_code;
                     if(clientId == shortCode){
                        var jobCodeObject = {};
                        jobCodeObject.jobCode = ''+_jobCodeObject.id;
                        jobCodeObject.clientId = clientId;
                        jobCodes.push(jobCodeObject);
                        break;
                     }
                  }
               }
               payload = {};
               payload.jobCodes = jobCodes;
               mc.setPayloadJSON(payload);
                                 
            ]]>
         </script>
         <property name="jobCodesCount" expression="count(//jobCodes)" scope="operation" />
         <property name="jobCodeIndex" value="0" scope="operation" />
         <iterate continueParent="true" id="clients" expression="//jobCodes" sequential="true">
            <target>
               <sequence>
                  <property name="tsheets.jobCodeObject" expression="json-eval($.)" />
                  <property name="tsheets.parentJobCode" expression="json-eval($.jobCodes.jobCode)" />
                  <property name="billiving.clientId" expression="json-eval($.jobCodes.clientId)" />
                  <tsheets.init>
                     <apiUrl>{$ctx:tsheets.apiUrl}</apiUrl>
                     <accessToken>{$ctx:tsheets.accessToken}</accessToken>
                  </tsheets.init>
                  <tsheets.listTimeSheets>
                     <startDate>{$ctx:tsheets.timeSheetStartDate}</startDate>
                     <endDate>{$ctx:tsheets.timeSheetEndDate}</endDate>
                     <jobCodeIds>{$ctx:tsheets.parentJobCode}</jobCodeIds>
                  </tsheets.listTimeSheets>
                  <property name="timesheetsCount" expression="count(//results/timesheets)" />
                  <filter xpath="get-property('timesheetsCount') != 0">
                     <then>
                        <!-- Calculate time entries and create Billiving items to create invoices. -->
                        <script language="js">
                        <![CDATA[
                           var timeSheetResult = mc.getPayloadJSON();
                           var timeSheets = timeSheetResult.results.timesheets;
                           var suplimentData_jobCodes = timeSheetResult.supplemental_data.jobcodes;
                           var jobCodeObject = eval("(" + mc.getProperty('tsheets.jobCodeObject') + ")");
                           var parentJobCode =  mc.getProperty('tsheets.parentJobCode');
                           var childJobCodes = {};
                           for(var key in timeSheets){
                              var timeSheet = timeSheets[key];
                              var jobCode = timeSheet.jobcode_id;
                              var _jobCode = 'cjc_'+jobCode;
                              if(!childJobCodes.hasOwnProperty(_jobCode)){
                                 childJobCodes[_jobCode] = {};
                                 childJobCodes[_jobCode]['ItemId'] = suplimentData_jobCodes[jobCode].id;
                                 childJobCodes[_jobCode]['ItemDescription'] = suplimentData_jobCodes[jobCode].name + ' (From - '+mc.getProperty('tsheets.timeSheetStartDate')+' To - '+mc.getProperty('tsheets.timeSheetEndDate')+')';
                                 childJobCodes[_jobCode]['ItemPrice'] = suplimentData_jobCodes[jobCode].billable_rate;
                                 childJobCodes[_jobCode]['ItemQuantity'] = timeSheet.duration/3600;
                                 
                              }else{
                                 childJobCodes[_jobCode]['ItemQuantity'] = childJobCodes[_jobCode]['ItemQuantity'] + timeSheet.duration/3600;
                              }
                              
                           }
                           var docItems = [];
                           for(var key in childJobCodes){
                              var docItem = childJobCodes[key];
                              docItems.push(docItem);
                           }
                           
                           mc.setPayloadJSON(docItems);
                                              
                        ]]>
                        </script>
                        <property name="billiving.docItems" expression="json-eval($.)" />
                        <!-- Create Billing Invoice -->
                        <billiving.init>
                           <apiUrl>{$ctx:billiving.apiUrl}</apiUrl>
                           <accessToken>{$ctx:billiving.accessToken}</accessToken>
                        </billiving.init>
                        <billiving.createInvoice>
                           <clientId>{$ctx:billiving.clientId}</clientId>
                           <docItems>{$ctx:billiving.docItems}</docItems>
                        </billiving.createInvoice>
                        <header name="Content-Encoding" action="remove" scope="transport" />
                        <filter source="$axis2:HTTP_SC" regex="200">
                           <then>
                              <property name="uri.var.billiving.invoiceId" expression="json-eval($.Id)" />
                              <property name="invoiceIdObject"
                                 expression="fn:concat('tSheets_jobCode:',get-property('tsheets.parentJobCode'),',billiving_invoiceId:',get-property('uri.var.billiving.invoiceId'))" />
                              <property name="status" value="success" />
                              <property name="message" value="Invoice has been successfully created." />
                           </then>
                           <else>
                              <property name="invoiceIdObject"
                                 expression="fn:concat('tSheets_jobCode:',get-property('tsheets.parentJobCode'))" />
                              <property name="status" value="error" />
                              <property name="message" expression="json-eval($.)" />
                           </else>
                        </filter>
                        <call-template target="responseHandlerTemplate">
                           <with-param name="id" value="{$ctx:invoiceIdObject}" />
                           <with-param name="activity" value="billiving_createInvoice" />
                           <with-param name="status" value="{$ctx:status}" />
                           <with-param name="message" value="{$ctx:message}" />
                        </call-template>
                     </then>
                  </filter>
                  <property name="jobCodeIndex" expression="get-property('operation','jobCodeIndex') + 1"
                     scope="operation" />
                  <filter xpath="get-property('operation','jobCodesCount') = get-property('operation','jobCodeIndex') ">
                     <then>
                        <loopback />
                     </then>
                  </filter>
               </sequence>
            </target>
         </iterate>
      </inSequence>
      <outSequence>
         <property name="messageType" value="application/json" scope="axis2" />
         <filter source="boolean(get-property('operation', 'responseString'))" regex="false">
            <then>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response": {
                     "process": "hubSpot_createInvoicesForTimeEntries",
                     "activityResponse": [
                     {
                     "activity":"tSheets_retrieveTimeSheets",
                     "status":"skipped",
                     "message":"Couldn't find timesheets to be processed."
                     }
                     ]
                     }
                     }
                  </format>
               </payloadFactory>
            </then>
            <else>
               <payloadFactory media-type="json">
                  <format>
                     {
                     "Response":
                     {
                     "process":"hubSpot_createInvoicesForTimeEntries",
                     "activityResponse":[$1]
                     }
                     }
                  </format>
                  <args>
                     <arg expression="get-property('operation', 'responseString')" />
                  </args>
               </payloadFactory>
            </else>
         </filter>
         <send />
      </outSequence>
   </target>
   <description />
</proxy>
Sample Request for retrieving time entries for a particular period from TSheets and creating an invoice in Billiving for book keeping purposes
{
	"hubSpot":{
		"apiKey":"982855ac-b43b-4c89-833b-eb9002379825"
	},
	"billiving":{
		"accessToken":"0b635066-0329-43a9-9f30-7ead387c45cb"
	},
	"tSheets":{
		"apiUrl":"https://malivera.tsheets.com",
		"accessToken":"S.2__96eb91af9a07d31d12f8f2f79a4249f9c85bc9d6",
		"startDate":"2015-08-01",
		"endDate":"2015-09-31"
	}
}

Note

 The following are the parameter descriptions:

  • tSheets.startDate: Start date in YYYY-MM-dd format to retrieve time sheets.
  • tSheets.endDate: End date in YYYY-MM-dd format to retrieve time sheets.