- 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]]
- First, create an empty directory and copy the files from the default sample Reddit package.
- If you don't have the
unigraph-package-samplespackage on your machine, you can download the zip file on the main page.
- If you don't have the
- 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
namefield ofpackage.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.
- Since package metadata is extracted in
- At the same directory, run
npx unigraph-packager. This utility will make this app into a.pkg.jsfile 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.
- 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 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 idsettings_page_reddit_) and the custom view of the settings page (near the top ofpackage.json, with idsettings-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
entitiesfolder - the process should be self-explanatory. - Now, we can go to the
executablesfolder, opensettingsViewReddit.jsxand 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
returnstatement provides the render result of the page.- The "Sign in with Reddit" button is displayed - and will run the executable
$/executable/add-reddit-accountafter 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).
- The "Sign in with Reddit" button is displayed - and will run the executable
- The long
- In the previous session, when the user clicks on the "Sign in with Reddit" button, the executable
$/executable/add-reddit-accountis 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 yourclient_idand (optionally)client_secretfor 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 athttp://<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.
- The function call
- 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_secretfor that. - The field
subscriptionsprovides a way to store sync states easily with Unigraph. For example, you can rename & change the definition of type to$/schema/reddit_feedand use that to store different sync tokens.
- 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
- 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 idupdate-reddit-subscriptionis 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": 1makes 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.
- The
- 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_accountobject you added earlier.
- Line 1-37 gets the currently logged-in user from the database, using DQL syntax (temporary). You should change
- TBC
- 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