Giter Club home page Giter Club logo

tractionsyncproxy's Introduction

Sync Process Overview

Overview:

The Salesforce.com – Google Sheets Data Synchronization app allows Sales teams to export their Sales data from Salesforce to a Google Sheet, update the data for multiple records in one sheet and have those updates reflected back in Salesforce automatically. Required fields and picklist values are respected in Google sheets, saving time and avoiding pollution of your Salesforce environment with dirty data.

Export Process:

  1. SFCD sends export request to the Heroku server.

  2. Heroku performs OAuth request for both SF and Google.

  3. Heroku retrieves data from SFDC.

  4. Heroku create/update Google Sheet document.

  5. Heroku attaches Google Web App script to Google Sheet.

Update Process:

  1. Google Sheet triggers the Web App when document is updated.

  2. Google Web App sends notification to Heroku.

  3. Heroku retrieves modified data from Google Sheet.

  4. Heroku sends data update request to SFDC.

  5. Heroku updates Google Sheet with success/error message from SFDC.

Heroku Sync Proxy

This is a node.js server that acts as a broker between salesforce.com and Google Sheets. It handles all the export and update requests, manages credentials, and displays progress to the user during exports.

The source code (and an up-to-date version of this document) can be found on GitHub: https://github.com/TractionOnDemand/TractionSyncProxy

SalesForce Exporter

This is primarily a Lightning component that sits on the Opportunity page layout. It makes a POST to the Heroku app to initiate a LIstView export.

Google Web App

This web app detects change events on the Google Sheet and sends notifications to the Heroku app when such changes occur.

Step by Step Deployment Instructions

Heroku Setup

  1. Download and Install Heroku Command Line Tools from: https://devcenter.heroku.com/articles/heroku-cli

a.  Select your Operating System

b.  Run the installation

    i.  Note: you may have to run the installation as the Admin user
        of your computer
  1. Create a Heroku account: https://signup.heroku.com/login

  1. Create a new Heroku App: https://dashboard.heroku.com/new

    a. Refer to the official Heroku documentation for detailed help: https://devcenter.heroku.com

b.  On the Settings tab, record the Domain of your new app.

    This will be referred to as <HEROKU_APP_URL> throughout
    this document.
  1. Add PostgreSQL to the Heroku app

    a. From the ‘Resources’ tab, enter ‘Postgres’ into the Add-ons search and select ‘Heroku Postgres’ from the search results.

b.  Pick your plan name and click the ‘Provision’ button.

    -   Eg. Pick “Hobby Dev” and click “Provision”

c.  Click into the new Postgres Database: “Heroku Postgres :: Database”

d.  From the new datastore page, scroll down and click the ‘View Credentials’ button.

e.  The URI value is the <DATABASE_URL>
  1. Setup Environment Variables.

    a. From the settings tab, click ‘Reveal Config Vars’

b.  add a new variable for the following KEY = VALUE pair

    NODE_PATH = ./server
  1. Download and Install Git on your local machine: https://git-scm.com/download/

  1. Install node.js, if not already installed.

    a. In a browser, go to: https://nodejs.org/en/download/

    b. Select your Operating System and download.

c.  Run the setup wizard.
  1. Checkout the node.js server from GitHub.

    a. Open the new Git bash console that you installed.

b.  Navigate to the folder where you want to copy the node.js server

c.  Type in the command prompt:

    git clone https://github.com/TractionOnDemand/TractionSyncProxy.git
  1. CD into the repo directory

    a. Type in the command prompt:

     cd TractionSyncProxy
    
  2. Add heroku as a remote.

    a. Type in the command prompt:

    git remote add heroku https://git.heroku.com/<HEROKU_APP_NAME>.git
    

    b. If you are a windows user, you may be asked to authenticate. You must authenticate from the command prompt, rather than the Git bash console.

    i.  Open the command prompt cmd.exe
    
    ii. Navigate to the TractionSyncProxy directory you created.
    
    iii. Type the command:
    
        heroku login
    
  3. Push to your heroku app.

    a. Type in the command prompt:

    git push heroku
    
  4. Run the database setup.

    a. Use the URL that you copied from step 3a) above.

    b. Open the URL in a browser: <HEROKU_APP_URL>/pg/setup_db

    c. optionally disable the setup in ./router/pg.js to prevent setup from running again. (will need to commit/push the change).

salesforce.com Setup

  1. Install the Managed Package.

    a. https://login.salesforce.com/packaging/installPackage.apexp?p0=04t50000000RYjE

    b. Click to install for all users.

    c. You will be prompted to Approve Third-Party Access:

d.  Select Yes, grant access… and click “Continue”
  1. Add the Custom Setting default value for the Heroku Endpoint URL.

    a. Go to: Setup -> Develop -> Custom Settings Google Sheet Sync (Manage)

b.  Add a new default organization level value:

    Endpoint URL = <HEROKU_APP_URL>/salesforce
    (e.g. https://your-heroku-app-name.herokuapp.com/salesforce)
  1. Add the Heroku App as a Connected App in SalesForce

    a. Setup -> Create -> Apps -> Connected Apps (New).

    b. Enable OAuth Settings.

    i.  Provide a name for the connected app (you can use your app name).
    
    ii. Enter your email address
    
    iii. Callback URL = <HEROKU_APP_URL>/salesforce/oauth
    
    iv. Selected OAuth Scopes
    
  • Full access (full)

  • Perform requests on your behalf at any time (refresh_token, offline_access)

    a. Record the ‘Consumer Key’ and ‘Consumer Secret’ for the next step.

  1. Back on your Heroku app, add the following environment variables:

    a. Heroku > Settings > click “Reveal Config Vars”

    SF_LOGIN_URL = https://login.salesforce.com/services/oauth2
    
    SF_REDIRECT_URI = <HEROKU_APP_URL>/salesforce/oauth
    
    * note that you must include the “https://” in the URI*
    
    SF_KEY = use the ‘Consumer Key’ from the previous step.
    
    SF_SECRET = use the ‘Consumer Secret’ from the previous step.
    
  2. Update the ‘Heroku Sync’ Remote Site settings with your Heroku App URL

    a. In Salesforce go to: Setup -> Security Controls > Remote Site Settings -> Heroku Sync -> Edit

    Remote Site URL = <HEROKU_APP_URL>
    
  3. Add the ‘List View Exporter’ Lightning component to the Opportunity page layout

    a. Switch to Lightning Experience if not already enabled.

    i.  Click on your name at the top of the screen.
    
    ii. Select “Switch to Lightning Experience”
    

    b. Go to an Opportunity record page.

    c. Click on the Gear icon at the top of the page -> Select “Edit Page”

    d. If you have not already done so, you will have to register a custom domain in order to add the custom lightning component.

    i.  Click on “Deploy My Domain” on the left navigation bar under “Custom”
    
    ii. Enter a domain name.
    
    iii. You will have to wait until the domain is registered.
    
    iv. Navigate back to the Opportunity Record page.
    
    v.  Click to Edit the page
    
    vi. Click on “Deploy My Domain” again.
    
    vii. Click on “Deploy to users”.
    

    e. Drag/Drop the ListViewExporter component onto the Opportunity page layout.

    i.  Navigate back to the Opportunity Record page.
    
    ii. Click to Edit the page
    
    iii. Drag the “List View Exporter” component onto the page layout.
    
    iv. Click Save
    
    v.  Click “Activate”
    
    vi. Select “Assign this page as the default record page” > Save
    
    vii. Click Save
    

    f. (optional) set the components configurable text labels.

    g. Click “Save”.

Google Web App Setup

  1. Create a project:

    a. open the Developer Console: https://console.developers.google.com

    b. select ‘Create project’ from the menu dropdown.

c.  Enter a project name then click ‘Create’ (this might take a few minutes)
  1. Enable Drive API and Sheets API

  1. Click ‘Credentials’ from the nav menu.

  2. Setup Credentials

    a. On the Credentials tab, select ‘OAuth client ID’ from the ‘Create credentials’ dropdown.

    b. Select ‘Web application’

    c. Enter a name for the web application

    d. Set the ‘Authorized JavaScript Origins: <HEROKU_APP_URL>

    i.  This may not be required.
    

    e. Set the ‘Authorized redirect URI’ to: <HEROKU_APP_URL>/google/callback

    f. Click Create

    g. Record the Client ID and Client Secret.

    (referred to as <GOOGLE_CLIENT_ID> and
    <GOOGLE_CLIENT_SECRET> in this document).
    
  3. On the ‘OAuth consent screen’ tab, enter all appropriate fields

    a. Enter the Product name shown to users

    b. Click Save

  4. Create a new Google Doc on your Google Drive.

    a. Navigate to https://drive.google.com

    b. Click “New” > select “Google Doc”

  5. From the Tools menu, select ‘Script editor…’

a.  This will open a Google doc called “Code.gs”
  1. Copy/paste the contents of <GIT_PROJECT_FOLDER>/webapp/google_sync_apps.gs into the Code.gs Google Doc

    a. Remove the current text from the file and replace with the text from the google_sync_apps.gs file.

  2. Save the project: File -> Save

    a. You will be asked to provide a name for the doc.

    b. Eg. SFDC Script Doc

  3. Add the Heroku app URL to Script Properties:

    a. File -> Project Properties

    b. Click on the “Script Properties” tab

c.  on the “Script properties” tab, add a new row with the following Property = Value:

    (remove any trailing slash from the URL)

    HEROKU_APP_URL = <HEROKU_APP_URL>
  1. Publish the app:

    a. Click on the “Publish” tab and select “Deploy as web app”

b.  Select the following preferences:

    i.  Project version = New

    ii. Execute the app as: User accessing the web app

    iii. Who has access to the app: Anyone

c.  Click to review your permissions in the prompt that asks for
    permission to access your data on google.

    i.  Click to Allow
  1. Copy the web app URL (referred to as <GOOGLE_WEBAPP_URL>) for entering into Heroku as a Config variable in the next steps.

  2. In your Heroku app, you will add additional Configuration Variables:

    a. Go into your Heroku app in a browser

    i.  Click on the Settings tab
    
    ii. Click on “Reveal Config Vars”
    
    iii. Create a new Config variable: GOOGLE_CLIENT_ID
    

    b. Go to the Google Developer Console in another tab in your browser

    i.  Click on the Credentials tab
    
    ii. Click on your Oauth 2.0 app credentials
    
    iii. Copy the Google Client ID
    

    c. In the Heroku app, paste the Google Client ID into the Config variable

    i.  Click “Add”
    
    ii. Create a new Config variable: GOOGLE_CLIENT_SECRET
    
    iii. In the Google Developer console copy the Client secret and
        paste it as the value in the config variable.
    

    d. In the Heroku app, click to “Add” another Config variable: GOOGLE_CALLBACK_URL

    i.  In the Google Developer console copy the “Authorized redict
        URIs” and paste into the GOOGLE_CALLBACK_URL in the latest
        Heroku Config variable.
    

    e. Click to “Add” another Config Variable: GOOGLE_WEBAPP_URL

    i.  Paste the Google WebApp URL that you copied from the
        document app deployment into the GOOGLE_WEBAPP_URL in the
        Heroku config variables.
    

    f. You should now have the following 4 additional config variables set in Heroku:

    GOOGLE_CLIENT_ID = <GOOGLE_CLIENT_ID>
    
    GOOGLE_CLIENT_SECRET = <GOOGLE_CLIENT_SECRET>
    
    GOOGLE_CALLBACK_URL = <HEROKU_APP_URL>/google/callback
    
    GOOGLE_WEBAPP_URL = <GOOGLE_WEBAPP_URL>
    

Congratulations!!

You have now successfully configured the apps. To use the app:

  1. Open your Salesforce org.

  2. Go into an Opportunity

  1. Select the list view to export and click on the “Export to Google” button

  2. Note that several permission screens will be displayed.

  3. You will have to accept to Leave Salesforce.

  1. Click Continue

  2. You may have to select your Google Account to generate the Google Sheet in, if you have multiple accounts.

  3. Select the appropriate account.

  4. You will then have to click to review permissions of the Google App in order to access data on your Google account.

  1. Click “Review Permissions”

  2. You will then have to allow the Google App to view and manage your spreadsheets in Google Drive, etc.

  1. Click “Allow”

  2. A workflow will then be displayed indicating what is taking place.

    a. Create Google Sheet

    b. Write Data to Sheet

    c. Open Google Sheet

  1. Once this has completed a new Google Sheet will open containing all of the Opportunities from the List View that you selected to export.

  1. You can now edit each of the Opportunity records inline and all of the changes will be pushed back into Salesforce!

    a. Picklist values will be presented according to your fields in Salesforce

    b. Validation rules will be respected when attempting to make changes.

    c. When a record is updated the “sync_status” field/column will be updated to indicate that the changes have been synced back to Salesforce.

tractionsyncproxy's People

Contributors

dougjod avatar tractionondemand avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

tractionsyncproxy's Issues

503 Error: Service Unavailable

I've completed all the steps to setup the connector, but I hit a 503 error when exporting a sheet. It looks like the issue is coming from format_list_data when it tries to access the "length" method that, for whatever reason, doesn't exist.

I realize that it's difficult to debug from your end with only this much information, but if you have any insight that would be helpful. Others reviewing the extension experienced the same issue.

Here's the relevant log excerpt from heroku:

2018-01-09T21:59:37.372422+00:00 app[web.1]: format_list_data Exception: TypeError: Cannot read property 'length' of undefined
2018-01-09T21:59:37.374966+00:00 app[web.1]: /app/server/salesforce/salesforce_utils.js:44
2018-01-09T21:59:37.374979+00:00 app[web.1]:     at emitTwo (events.js:87:13)
2018-01-09T21:59:37.374970+00:00 app[web.1]:                                                              ^
2018-01-09T21:59:37.374968+00:00 app[web.1]:             for (var y = 0; y < req.sf_sync.list_data.columns.names.length; y++) {
2018-01-09T21:59:37.374978+00:00 app[web.1]:     at Request.self.callback (/app/node_modules/request/request.js:186:22)
2018-01-09T21:59:37.374981+00:00 app[web.1]:     at emitOne (events.js:77:13)
2018-01-09T21:59:37.374984+00:00 app[web.1]:     at IncomingMessage.g (events.js:260:16)
2018-01-09T21:59:37.397644+00:00 app[web.1]: npm ERR! node v4.2.6
2018-01-09T21:59:37.374975+00:00 app[web.1]: TypeError: Cannot read property 'names' of undefined
2018-01-09T21:59:37.374980+00:00 app[web.1]:     at Request.emit (events.js:172:7)
2018-01-09T21:59:37.374982+00:00 app[web.1]:     at Request.emit (events.js:169:7)

Thanks for your work!

format_list_data Exception: TypeError: Cannot read property 'length' of undefined

I get an error on line #44 of /app/server/salesforce/salesforce_utils.js
Cannot read property 'length' of undefined
Has anyone else seen this?

Full error from Heroku log

2018-03-06T22:38:59.199558+00:00 app[web.1]: format_list_data Exception: TypeError: Cannot read property 'length' of undefined
2018-03-06T22:38:59.201776+00:00 app[web.1]: /app/server/salesforce/salesforce_utils.js:44
2018-03-06T22:38:59.201780+00:00 app[web.1]:             for (var y = 0; y < req.sf_sync.list_data.columns.names.length; y++) {
2018-03-06T22:38:59.201783+00:00 app[web.1]:                                                              ^
2018-03-06T22:38:59.201784+00:00 app[web.1]: 
2018-03-06T22:38:59.201785+00:00 app[web.1]: TypeError: Cannot read property 'names' of undefined
2018-03-06T22:38:59.201787+00:00 app[web.1]:     at Request._callback (/app/server/salesforce/salesforce_utils.js:44:62)
2018-03-06T22:38:59.201788+00:00 app[web.1]:     at Request.self.callback (/app/node_modules/request/request.js:186:22)
2018-03-06T22:38:59.201790+00:00 app[web.1]:     at emitTwo (events.js:87:13)
2018-03-06T22:38:59.201791+00:00 app[web.1]:     at Request.emit (events.js:172:7)
2018-03-06T22:38:59.201792+00:00 app[web.1]:     at Request.<anonymous> (/app/node_modules/request/request.js:1163:10)
2018-03-06T22:38:59.201793+00:00 app[web.1]:     at emitOne (events.js:77:13)
2018-03-06T22:38:59.201795+00:00 app[web.1]:     at Request.emit (events.js:169:7)
2018-03-06T22:38:59.201796+00:00 app[web.1]:     at IncomingMessage.<anonymous> (/app/node_modules/request/request.js:1085:12)
2018-03-06T22:38:59.201797+00:00 app[web.1]:     at IncomingMessage.g (events.js:260:16)
2018-03-06T22:38:59.201798+00:00 app[web.1]:     at emitNone (events.js:72:20)
2018-03-06T22:38:59.212443+00:00 app[web.1]: 
2018-03-06T22:38:59.220707+00:00 app[web.1]: npm ERR! Linux 4.4.0-1012-aws
2018-03-06T22:38:59.221140+00:00 app[web.1]: npm ERR! argv "/app/.heroku/node/bin/node" "/app/.heroku/node/bin/npm" "start"
2018-03-06T22:38:59.221413+00:00 app[web.1]: npm ERR! node v4.2.6
2018-03-06T22:38:59.222500+00:00 app[web.1]: npm ERR! npm  v3.5.4
2018-03-06T22:38:59.222750+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2018-03-06T22:38:59.223073
+00:00 app[web.1]: npm ERR! [email protected] start: `node server.js`
2018-03-06T22:38:59.223247+00:00 app[web.1]: npm ERR! Exit status 1
2018-03-06T22:38:59.223449+00:00 app[web.1]: npm ERR! 
2018-03-06T22:38:59.223633+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script 'node server.js'.
2018-03-06T22:38:59.223826+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.
2018-03-06T22:38:59.224008+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the sf-google-sync package,
2018-03-06T22:38:59.224255+00:00 app[web.1]: npm ERR! not with npm itself.
2018-03-06T22:38:59.224431+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:
2018-03-06T22:38:59.224605+00:00 app[web.1]: npm ERR!     node server.js
2018-03-06T22:38:59.224784+00:00 app[web.1]: npm ERR! You can get information on how to open an issue for this project with:
2018-03-06T22:38:59.224963+00:00 app[web.1]: npm ERR!     npm bugs sf-google-sync
2018-03-06T22:38:59.225135+00:00 app[web.1]: npm ERR! Or if that isn't available, you can get their info via:
2018-03-06T22:38:59.225314+00:00 app[web.1]: npm ERR!     npm owner ls sf-google-sync
2018-03-06T22:38:59.225487+00:00 app[web.1]: npm ERR! There is likely additional logging output above.
2018-03-06T22:38:59.229050+00:00 app[web.1]: 
2018-03-06T22:38:59.229304+00:00 app[web.1]: npm ERR! Please include the following file with any support request:
2018-03-06T22:38:59.229479+00:00 app[web.1]: npm ERR!     /app/npm-debug.log


invalid arguments!

I keep getting invalid arguments when google tries to authorize the script.

Also nothing happens to ask when I click the button in SF.

I have redone the google portion numberous times and have retraced my steps. I cannot seem to figure out what is wrong.

Auth tokens get out of sync.

If a user manually revokes their SFDC or Google token, the Heroku server does not ask the user to re-authenticate and will try (and fail) to use the existing stored credentials. There is minimal error reporting back to the user when this happens.

The only workaround is to manually remove that user's credentials from the PostgreSQL database.

Step 34 Not Working

Export to Google button is inactive - It shows the error no items in the lists: whereas they are multiple items present.

Encrypt tokens in database

OAuth tokens are currently stored in plain text in the database and should be encrypted before getting saved. Can potentially use a combination of a OrgId, UserId, and existing SF and GApp key/secret config variables to salt the encryption key.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.