Skip to content

Latest commit

 

History

History
49 lines (48 loc) · 25.7 KB

File metadata and controls

49 lines (48 loc) · 25.7 KB

Introduction

  • In this page, we're going to explore the whole process of setting up a custom Unigraph integration. We use our Reddit feed integration as an example for what's possible in a completely third-party app on Unigraph, and guide you through the process of making one for your favourite service.
  • If you want a deep-dive into how Unigraph packages work, see [[Anatomy of Unigraph Package]]

Setting up the Unigraph environment

  • First, create an empty directory and copy the files from the default sample Reddit package.
    • If you don't have the unigraph-package-samples package on your machine, you can download the zip file on the main page.
  • This directory now has all the project files needed for it to be used with Unigraph, and we'll start from here.
    • Since package metadata is extracted in package.json, feel free to edit it to your desire!
    • The package name is defined in the name field of package.json, and it's used to identify unique packages. In order to not overwrite the existing Reddit package in your Unigraph, you should change it to a name that works for you.
  • At the same directory, run npx unigraph-packager. This utility will make this app into a .pkg.js file that Unigraph can import. If everything is right, you'll see this:
    • Successfully generated Unigraph package at <Package path>.
  • Now, (if you changed the package name), you can import the package in Unigraph!
    • Navigate to the Unigraph section of the left sidebar in Unigraph, then click on Packages.
      • image.png
    • Then, click the Add package (overwrite) button at the top, and select the package in the path given by unigraph-packager.
    • Wait a few seconds, and you can see the total number of packages increasing, and that your package has been loaded into Unigraph.

Your settings page

  • Your settings page is where users will log into their accounts, and configure various options for your integration.
  • The settings page consists of 2 parts: the settings page object itself (at the bottom of package.json, with id settings_page_reddit_) and the custom view of the settings page (near the top of package.json, with id settings-view-reddit_).
    • The settings page itself is simply a Unigraph object in the database, with properties defined to let Unigraph know how to show it in the settings menu.
    • The custom view is a React functional component that is dynamically rendered when the settings page for your package is opened.
      • Don't worry - you wouldn't need to learn React to continue! We've encapsulated most complications away, and you should be able to get a hang of it really quick.
  • To change the settings page, you can first change the settings page object located in the entities folder - the process should be self-explanatory.
  • Now, we can go to the executables folder, open settingsViewReddit.jsx and see how the settings page work.
    • The long React.useEffect(() => { block: it subscribes, through a DQL query, the account(s) currently signed-in to Reddit. You generally don't need to edit this part - it will be explained in more detail in the OAuth section next.
    • Now we can see how the settings page is rendered - near the bottom of the file, the return statement provides the render result of the page.
      • The "Sign in with Reddit" button is displayed - and will run the executable $/executable/add-reddit-account after being clicked. This function will do the OAuth flow with Reddit and connects your Reddit account to Unigraph.
      • After that, we're consuming the data from the subscription above to get the account info, including the username and currently subscribed feed (in the case of this Reddit integration, it's just the home feed for now).

OAuth with third-party API, and storing tokens in Unigraph

  • In the previous session, when the user clicks on the "Sign in with Reddit" button, the executable $/executable/add-reddit-account is run to let you sign in to Reddit via OAuth, and then saves the user account details (including access tokens) in the database.
  • The executable is located at executables/addRedditAccount.js, and most of them should be self-explanatory, with a few extra pointers to note:
    • The function call const appClientId = unigraph.getSecret('reddit', 'client_id'); is currently not available in custom packages. Instead, you can hard-code your client_id and (optionally) client_secret for now.
    • The function const oauthResponse = await unigraph.awaitHttpCallback('reddit'); is a Unigraph API function that's only available on the backend. It waits for an HTTP GET request at http://<server location>:4001/callback?key=reddit, then returns the response of type Request in Express.
    • We currently only have a few npm packages available for backend, and the full list that's included in Unigraph builds can be found here. In the future, you'll be able to add custom packages as dependencies.
  • After the OAuth flow is completed, we'll likely have a username, display name, access token (either a bearer token or a key/secret pair), and refresh token. We have a convenient datatype for storing these information in the database, called $/schema/internet_account.
    • Line 37-56 in the executable shows a way to add these information into Unigraph - alternatively, if the access token is a key/secret pair, you can also specify the field access_token_secret for that.
    • The field subscriptions provides a way to store sync states easily with Unigraph. For example, you can rename & change the definition of type to $/schema/reddit_feed and use that to store different sync tokens.

Setup recurring script to sync data

  • Now that you have set up a sign-in flow, you can set up a recurring script to sync your data every once in a while.
  • In package.json, the second executable with id update-reddit-subscription is such an executable.
    • The "periodic": "*/3 * * * *" field specifies how frequently it should be run in Cron syntax - here, it says to run every 3 minutes.
    • The "concurrency": 1 makes sure that if another call to the executable happens while it's already running (for example, if the initial sync takes more than 1 minute), the second one will not be executed.
  • This executable is located at executables/updateRedditSubscriptions.js.
    • Line 1-37 gets the currently logged-in user from the database, using DQL syntax (temporary). You should change "Reddit" on line 10 to the site name of the $/schema/internet_account object you added earlier.
  • TBC

Optional: add custom data type and view

  • If you're syncing objects that is not within the default packages (e.g. YouTube videos, or Reddit posts), you'll probably need to add a custom data type and corresponding view to store and display your data correctly.
  • TBC