# Welcome to Frigg!

Developing integrations as easy as \`npm install\`

Welcome to Frigg Framework Documentation. Frigg is an open source serverless framework for developing integrations at scale. This documentation will help you get started with Frigg, understand its core concepts, and contribute effectively.

{% hint style="success" %}
**"TLDR, let me get my hands into the code!" \~ You, maybe**

Sure, we hear you. [**Check out our Quick Start tutorial.**](/tutorials/quick-start)

For our thorough readers, read on!
{% endhint %}

## Integrations shouldn't be that hard to build and maintain...

Frigg was built with the core principles that user-facing self-serve software integrations should be:

* Easy to Develop
* Inexpensive to run
* Modular and Extensible
* Easy to Scale
* Easy to maintain

This is our answer to the question "hasn't this already been done before?"

Modern stack; easy to understand; fast to develop and deploy; comprehensive enough to cover any use case; fully open source. Interoperability, the way it should be.

## Navigating the Docs

These docs should be your go-to resource for all things Frigg related. Secondary are GitHub READMEs and Slack community channels.

We are attempting to embrace a [Diátaxis](https://diataxis.fr/) approach to documenting Frigg. Any recommendations are welcome!

In general, there are four main areas of the docs, and four supplemental sections

### Main Documentation Areas

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f9d1-1f4bb">🧑‍💻</span> Tutorials (Learning)</td><td>Hands-on activities to learn how to use Frigg, and how to think about and build high quality integrations.</td><td><a href="/pages/uqGIBi7zt49KwnUPnKff">/pages/uqGIBi7zt49KwnUPnKff</a></td><td><a href="/files/1gp9yf6oncBhVbwglg1x">/files/1gp9yf6oncBhVbwglg1x</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="2705">✅</span> How-To Guides (Goals)</td><td>In-depth directions for achieving different integration goals with Frigg, both general and on specific app/integration marketplaces.</td><td><a href="/pages/QULX8k4sp9VVEpn3jBAz">/pages/QULX8k4sp9VVEpn3jBAz</a></td><td><a href="/files/f0O1hbA0QkrITiuptd8Q">/files/f0O1hbA0QkrITiuptd8Q</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f4d6">📖</span> Reference (Information)</td><td>Technical definitions for all things Frigg. Classes, Objects, Methods, APIs, and more</td><td><a href="/pages/N4Uty6OkKetI1nEpnfXn">/pages/N4Uty6OkKetI1nEpnfXn</a></td><td><a href="/files/pzAOMaTDZ7CVJg7EK6TQ">/files/pzAOMaTDZ7CVJg7EK6TQ</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f4ad">💭</span> Explanation (Understanding)</td><td>Here you'll find our thought processes for building Frigg the way we have, and for how we think about integration development</td><td><a href="/pages/c1fSpbF0LQpMwNU18ii5">/pages/c1fSpbF0LQpMwNU18ii5</a></td><td><a href="/files/KuggOy4U8eMmZy4rptUS">/files/KuggOy4U8eMmZy4rptUS</a></td></tr></tbody></table>

### Supplemental Documentation Areas

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f50c">🔌</span> API Modules</td><td>Documentation for each API module published in Frigg's main library.</td><td><a href="/pages/tbrCKTuSaKUmSQhNK9rT">/pages/tbrCKTuSaKUmSQhNK9rT</a></td><td><a href="/files/epiEJdEiB4Dk8hzr9fDA">/files/epiEJdEiB4Dk8hzr9fDA</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f91d">🤝</span> Contributing</td><td>All things contributing to Frigg from as little as a typo-fixer to as deep as a core maintainer.</td><td><a href="/pages/OTC2kyR1ZnJCMOZT8HAA">/pages/OTC2kyR1ZnJCMOZT8HAA</a></td><td><a href="/files/SqCx3pnUPYEOfPpWoCjX">/files/SqCx3pnUPYEOfPpWoCjX</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f4de">📞</span> Support</td><td>Notes about how to get support</td><td><a href="/pages/iJwInM7d0Gk5BWRJK0S9">/pages/iJwInM7d0Gk5BWRJK0S9</a></td><td><a href="/files/xPCAr8Mm8oj9PvmGznnJ">/files/xPCAr8Mm8oj9PvmGznnJ</a></td></tr><tr><td><span data-gb-custom-inline data-tag="emoji" data-code="1f5fa">🗺️</span> Roadmap</td><td>The short, medium, and long term features and opportunities roadmap for Frigg</td><td><a href="/pages/7amZcZtkeG1baoBvOawY">/pages/7amZcZtkeG1baoBvOawY</a></td><td><a href="/files/t83JMuy8WtRAi5VFygm5">/files/t83JMuy8WtRAi5VFygm5</a></td></tr></tbody></table>

## Before you go any further, some quick FAQs

<details>

<summary>How does Frigg define "Integration?"</summary>

Application Programming Interfaces (APIs) are everywhere in software development. They can be made for SDKs, hardware, internal modules, HTTP requests to external systems, and more.

Frigg is focused on building integrations between separate software systems, powered the majority of the time via HTTP APIs.&#x20;

An integration, then, is the code that is used to "glue" these APIs together; an integration record is state managed by the software to keep track of which accounts and what settings a user desires.

At it's core, Frigg is intended to help developers build all types of integrations. And as we grow our footprint and community, we are undoubtedly going to see support added for enhanced features depending on your type of integration.&#x20;

To start, however, our roadmap and framework is focused on one specific use case - software teams building native integrations to external systems for end-user integration. **In a phrase: rapidly enabling technology partnerships.**

</details>

<details>

<summary>Who is Frigg For... Internal Integrations? Powering your Software? Enabling your Users?</summary>

There are three potential use cases for Frigg that we currently use internally at Left Hook.

* **Internal Business Process Automation-** This is the kind where you get notifications from GitHub to your Slack account; or where you have a cron job that every week summarizes and creates a report in Google Sheets, and emails out to relevant audiences; really, anything to help your backoffice flow smoother. This is squarely in the realm of iPaaS tools today. \
  \
  The primary audience for these integrations are internal users of your organization.<br>
* **Product and Productized Service Automation-** We view these as integrations that are powering your own software or service. Twilio integration to send text message alerts whenever a given event happens in your app. Webform piping to a database kicking off a drip campaign in your onboarding tool. Project completion kicking off an invoice to your clients with a summary of hours spent to date pulled from your time tracking software. \
  \
  There's a potential overlap with the first category, but it's most helpful to think of integrations to tools that eventually impact end users/customers of your software or service. <br>
* **End User Integration Enablement-** These are the integrations powering technology partnerships. Allowing users to connect their Slack account to your app, or their HubSpot account, or their Salesforce account, or go on down the line. By doing so, they adopt prebuilt workflows and automations that you've product managed to optimize the "better together" experience.&#x20;

Should you desire to use Frigg for each of these, we recommend creating 3 separate Frigg applications, as each one has a different user base, compute needs, and risk profile.

For now, it's critical to call out that Frigg is focused on the last bucket- End User Integration Enablement. Frigg is focused on powering your integration directory, and power the integrations your users choose to enable and configure.

Over time, there will be documentation and features focused on the other two buckets. So keep an eye on this space! But keep that in mind as you read on.

</details>

<details>

<summary>Frigg Explained to Partnership Leaders &#x26; Non-Technical People</summary>

The Frigg Integration Framework is a software development tool intended to help engineers build integrations faster.

While we all know that new "tech partnerships" unlock business opportunities, integration development is a complex, product-driven process performed by engineers and designers. Partnership leaders can't conjure new integrations into existence; product & engineering resources must be engaged and supported.

Given these dynamics, partnership leaders often seek *external* vendors and tools to get integrations built. This search brings them to Frigg and [Left Hook](https://lefthook.com).

Before you introduce Frigg to your engineering colleagues, partnership leaders should understand Frigg at a non-technical level. Our [Non-Technical Overview Doc](https://docs.google.com/document/d/e/2PACX-1vRzCTIUhUj5NC5CKIOhn36NGu6TbUPMwMF5-hFLJ2fuhfrCJ2VXnabtxqE429iP1CxPPgPyhzez41jk/pub) is intended to provide this context and support your internal advocacy for Frigg.

Meanwhile, Frigg's documentation site is targeted at engineers and product leaders who will need to understand the framework as a development tool.

If you're ready to introduce Frigg to your technical colleagues, share this documentation site. Our [live demo site](https://demo.friggframework.,org) is also instructive to both technical and non-technical audiences as well.

Have questions? Let's [connect](/support/support)!

</details>

<details>

<summary>Frigg: What's in a name?</summary>

* Frigg is Odin's wife in Norse mythology
* Goddess of **marriage** and **partnerships**
* She flies the earthly skies as a falcon
* She is known in folklore as the **“weaver of clouds”**

The Frigg Integration Framework powers integrations between software companies, the majority of which are in the cloud, speeding up time to live on tech partnerships.

Read more about Frigg on [Wikipedia](https://en.wikipedia.org/wiki/Frigg).

</details>

## Frigg Explained to Developers

Frigg is the framework you would have built to develop integrations, if you had unlimited resources and time. The added difference is the promise of Open Source-- i.e. a community of developers collaborating to solve the same core set of problems over and over again. This is something you could never do internally.

The Frigg Framework is an opinionated set of development tools, modules, classes, and plugins built with modern software development teams in mind. Frigg will have you up and running out-of-the-box with a flexible set of tools to help rapidly add integrations that your end users can self-serve.

Frigg handles integration listing, authentication, and configuration out-of-the-box, built on a scalable serverless architecture. It includes a growing library of prebuilt API Modules to greatly reduce time to "wow." Along with the core "out of the box" features, the framework contains primitives to help address and flex to any use case.

{% hint style="info" %}

#### A Note on Basic Architecture

A Frigg Application is predominantly a backend microservice, with an optional frontend. Most Frigg adopters already have an existing frontend UI built using a framework of their choice, or will bake integration UX into their product's core code. Frigg ships with a simple library of components to get you started quickly. See more details about frontend options here.

In the backend, Frigg is based on the serverless.com framework. This key piece of technology and the underlying compute/architecture under the hood provides a number of advantages:

* Infrastructure-as-Code- The need to manually configure resources on the host provider is greatly reduced
* Deployable to your favorite host- AWS, GCP, Azure, any a list of many more are available
* Horizontal Scalability
* Pay as you go
  {% endhint %}


# Learning Frigg

## Tutorials are for learning

Get Frigg up and running locally using our Quick Start Tutorial. More advanced tutorials are in progress.

{% content-ref url="/pages/DfdkEmGsGj5zh2hub823" %}
[Quick Start Tutorial](/tutorials/quick-start)
{% endcontent-ref %}


# Quick Start Tutorial

### Getting Started

Aloha! Ready to dive into using Frigg? Let’s get a HubSpot integration (or what HubSpot calls an "app") up and running quickly. \
\
This exercise will guide you through setting up a Frigg app locally, integrating it with HubSpot, and experiencing the magic in real-time.&#x20;

IMPORTANT: Running Create Frigg App requires several software development packages to be installed locally on your computer. While each prerequisite tool is fairly easy to install and configure, you may want to have an engineer available for troubleshooting.

### Prerequisites

Before we start, make sure you have:

* [Node.js and npm](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) installed
* [Git installed](https://git-scm.com/)&#x20;
* [Docker installed](https://www.docker.com/products/docker-desktop/) and running on your machine
* A [HubSpot Developer Account](https://app.hubspot.com/signup-hubspot/developers?utm_campaign=create-frigg-app)
* Your favorite IDE installed and ready to use

### Overview

Running the `create-frigg-app` command will generate a Frigg application that is deployable to your own infrastructure accounts in minutes.

Let's get started with `Create Frigg App` and unpack the magic as we go.

{% hint style="info" %}
**What is HubSpot and why use it in this tutorial?**

HubSpot is a popular marketing and CRM tool that helps businesses manage customer interactions. In this exercise, we use HubSpot to demonstrate how your Frigg App connects with external APIs.\
\
Setting up a HubSpot app lets you see how to connect, authenticate, and pull data from an external service. HubSpot provides an easy way understand integration basics in a common context.
{% endhint %}


# Initialize with Create Frigg App (CFA)

### Use `npx` to Create the App

Be sure to double-check that you have all the [prerequisite tools installed](/tutorials/quick-start) before attempting this tutorial.

Open your terminal and cd to a location where you want to install your Frigg application. Then run the following command to create a new Frigg app, replacing `[my-app-integrations]` with your desired app name:

```
npx create-frigg-app [my-app-integrations]
```

{% hint style="info" %}
**Note on naming:** We recommend naming your Frigg app something descriptive that reflects its purpose as a microservice that powers integrations; For example, "my-app-integrations" is a good fit.
{% endhint %}

This process might take a couple of minutes to complete, but at the end of it you should see something like this in your terminal:

<figure><img src="/files/3JR99UyBu78Ihl23DVgi" alt=""><figcaption><p>Your terminal once Create Frigg App is completed</p></figcaption></figure>

{% hint style="warning" %}
During the installation process, you will likely encounter warnings related to deprecated dependencies and Git initialization errors. These warnings are expected and will not impact your ability to run Frigg successfully. We are working to resolve any/all warnings, but we do not believe they indicate any acute security or functionality concerns. If you have any concerns, please contact us.
{% endhint %}

Now navigate to your newly created app directory using the following command:

```
cd [my-app-integrations]
```

Congrats! You've just successfully scaffolded and installed your Frigg app. Continue with further configuration and customization.


# Configuration

We've streamlined the setup process to make it as smooth as possible. We've pre-configured several environment variables that apply universally to all Frigg users upon installation. All that's left for you to do is to add your personal HubSpot credentials to connect to your app:

### Set up your HubSpot App

To add your HubSpot credentials, open the `.env` file located in `backend/*.env` with your IDE and have it ready to paste the information we'll gather in the next steps.

Go to your HubSpot account and create a new HubSpot App, and explore HubSpot if you're not familiar with it. Inside your HubSpot App, head to the "Auth" Tab, next to "App Info," where your can find your app settings.

<figure><img src="/files/9dIHNJbh2tYAz2hO1DTz" alt=""><figcaption><p>HubSpot's Auth tab for your app</p></figcaption></figure>

Now copy your Client ID and Client Secret into the `HUBSPOT_CLIENT_ID` and `HUBSPOT_CLIENT_SECRET` fields in the `.env` file. In the same file, add `oauth` to the HUBSPOT\_SCOPE array.\\

In HubSpot's tab, click the `+Add new scope` button, search for and add the scopes listed in your `.env` file.

<figure><img src="/files/3OIQPe6m0AG0Tlqz3afA" alt=""><figcaption><p>Your scopes should look like this after adding them</p></figcaption></figure>

Next, under the "Redirect URLs" section in the "Auth" tab, add `http://localhost:3000/redirect/hubspot` as a redirect URI.

<figure><img src="/files/OMWO1VYu1GrxFFb4Ubn3" alt=""><figcaption><p>Here you can set up your redirect locations</p></figcaption></figure>

Save your changes in both the `.env` file and HubSpot Auth settings.

Finally, from HubSpot's Developer home, create a new developer test account. This will prepare your app for integration and testing.

With all these settings configured, you're now ready to start your Frigg application.


# Start Your Frigg App

Ready to see Frigg in action? Let's start it up!

Make sure you're in the root directory of your application, then use:

```
npm run start
```

Your browser should open to `http://localhost:3000` and you should see your Login screen.

<figure><img src="/files/kP81Y71lKgC92RBQiKZK" alt="" width="328"><figcaption><p>Login screen of your Frigg app</p></figcaption></figure>

Before you continue, make sure that both your frontend and backend are running. An easy way to know is to check if your terminal looks something like this:

<figure><img src="/files/vizUcTqJAPYKzy6S6Ny0" alt="Console log displaying the backend server being &#x22;ready&#x22; on localhost:3001"><figcaption><p>The terminal output shows the backend server running locally, with a list of active routes and endpoints available for testing and development</p></figcaption></figure>

If your terminal shows that the backend is also running, you can now experience with your app as an end-user and connect it to see live data coming through!


# Connecting and Seeing Live Data

If you haven't already, select the "Create account (demo user)" option from the Login menu. A new user will be created for you with the pre-populated data you see on screen.

After receiving a successful confirmation message, you're now able to log in as the Demo User.

You will see a directory with HubSpot as an available connection.

<figure><img src="/files/h80dsmYE68KHaZm0mLtk" alt=""><figcaption><p>Your Dashboard in Frigg with the HubSpot Integration Available for Testing</p></figcaption></figure>

Click on the "Connect" button and complete HubSpot's authorization flow.

When finished, you should see a connected HubSpot card. Now it's time to see your app in action with live data from HubSpot!

### "No Data Available" error

Select "Get Sample Data" from the HubSpot app dropdown menu to see live data fetched from your test account.

Note that you might receive a "No data available" message. This is totally normal, given that we didn't add any info to your HubSpot account. There's nothing for our integration to fetch (yet).

<figure><img src="/files/TOyx1GBBUnu8o7XAE3lO" alt=""><figcaption><p>Oops! Looks like we forgot to add some test data to HubSpot</p></figcaption></figure>

### Adding Test Data to HubSpot

To fix this, let's add some test data to your HubSpot account. From your HubSpot dashboard, you should go to the "Deals" section in the CRM menu.<br>

Click "Create Deal" to manually add details and save, or use the "Import" option to upload a CSV file with test data.

<figure><img src="/files/vi5B9F4OaMDNnq6i73bI" alt=""><figcaption><p>You can find the Deals section inside the CRM menu</p></figcaption></figure>

{% hint style="info" %}
For more detailed instructions on how to add test data, visit the [HubSpot documentation](https://developers.hubspot.com/docs/api/crm/deals).
{% endhint %}

Once you've added test data, refresh the page and select "Get Sample Data" again. Now you should see Deals data displayed in your app. This confirms that everything is connected and working correctly!

<figure><img src="/files/gZAeRA8RLaCxCSsEM4BF" alt=""><figcaption><p>We see you, Antique Star Wars Droids collection!</p></figcaption></figure>

***

And that’s it! You’ve successfully created and configured your Frigg app with HubSpot. Time to explore and have fun with your new setup!


# Updating the Integration Logic

Now that your Frigg app is installed fresh out-of-the-box and your data is returning from your connected HubSpot account, let's pull data from another section within the same HubSpot account.&#x20;

Roll up your sleeves- now it’s time to get your hands in the code and customize your integration.

## Getting Started

Open your Frigg app project in your IDE. In the backend folder, look for the `/src/integrations` directory and open your `HubSpotIntegration.js` file.

## Understanding `HubSpotIntegration.js`

This file is where all the integration magic happens. It tells Frigg which API modules should be connected to use the integration and contains all of the integration logic. Here’s a simple breakdown:

* **API Modules**: Specifies which API modules are part of the integration.
* **Display Information**: Defines the display (description, label, categories, etc.) for the frontend.
* **Lifecycle Event Handlers**: Provides code/handlers for the lifecycle events of the integration (onCreate, onUpdate, onDelete).
* **Configuration Options**: Determines what users can configure for the integration (getConfigOptions).
* **Event Handlers**: Expands on the events that should trigger flows in the integration and defines handlers for those events.
* **User Actions**: Defines user actions available for leveraging the integration.

The power of this file lies in its ability to manage all aspects of the integration from a single point of entry. This allows for quicker development and easier maintenance.

## Swapping the Data Source

In the `HubSpotIntegration.js` file, find the `getSampleData` method. This is where the backend route fetches the data to display in the frontend.\
\
Update the code inside to fetch data from HubSpot’s "Companies" instead of "Deals" by replacing the original code with the following and saving the changes:

```javascript
async getSampleData() {
        const res = await this.target.api.listCompanies()
        console.log(res.results.length)
        const formatted = res.results.map(company => {
            const formattedCompany = {
                id: company.id,
                createdAt: company.createdAt,
                ...company.properties
            }


            return formattedCompany
        })
        return {data: formatted}

    }
```

To apply these changes, restart your Frigg app by terminating the backend process (command or ctrl & C) and running:

```
npm run start
```

This ensures the Frigg app backend service is updated with the new data fetching logic.

## **Testing Your Changes**

Go to your HubSpot account and add some company data manually or by importing a CSV file. For detailed steps, refer to the Connecting and Seeing Live Data section. Now refresh your app to see the new data displayed.

***

{% hint style="info" %}
Obviously, this is just a small change to the existing integration logic, not a fully fledged new feature. But one small change to the code has the potential to make a big impact for your integration users. Feel free to keep editing and exploring to get a feel for how simple it is to modify your existing integration logic, or check out our more advanced guides and tutorials to add more robust features.&#x20;
{% endhint %}

In our next section, we'll show how easy it is to get up and running with a fully new integration.&#x20;


# Advanced Tutorials


# Deploying your Frigg Application


# Deploying to AWS

Frigg is built using Infrastructure As Code, namely via the serverless.com framework. We have tried to stay close to basic as possible with deploy instructions and implementation.

To run a deploy, you can follow the serverless cli commands prompts or setup instructions, though we attempt to capture the basic commands below.

**NOTE-** Support for AWS comes out of the box. Contact Left Hook (or see updated documentation) for more details on how to deploy to stacks other than AWS

## VPC setup

Before you run your first deploy, there are a few things to confirm manually in your serverless.yml. If you'd like to deploy your lambdas behind a VPC out of the box, you'll want to fill in the corresponding security group ids and subnet ids in the custom > \[vpc] section of yaml.

Your lambdas must be allowed to make external API requests, and thus the subnets must be configured to allow access through a NAT Gateway or other similar service. This README cannot cover all of the permutations for AWS networking setups. We can assist on case base case basis, but strongly advise you to use a knowledgeable AWS resource if you choose to leverage VPCs in your setup.

## Secrets Manager for ENVs

Your Frigg Application has been configured to load envs from the secret found at the SECRET\_ARN variable. This is currently set to reference the output of the CloudFormation resource we've provided called "Frigg ENV Secret". We like this approach as it tightly couples a set of secrets/envs for each stage of deploy to the serverless.yml. However, to change this, one just needs to modify the value of SECRET\_ARN to whatever you choose.

Importantly, please review the comments of the serverless.yml around the Lambda Secrets Extension layer; this is a public Lambda Layer provided by AWS aimed at keeping AWS API requests low; you can read [more about it here](https://docs.aws.amazon.com/systems-manager/latest/userguide/ps-integration-lambda-extensions.html#ps-integration-lambda-extensions-add).

## Testing the packaging and running your first deploy

To run your first deploy:

1. Make sure you have proper AWS credentials setup locally or in your CD pipeline. See most recent serverless docs to confirm the recommended level of permissions
2. If you'd like to dry run/confirm your app builds as expected, run the `serverless package` command with your desired `--stage` flag
3. Once you're confident your code runs well locally and the build succeeds, you can deploy with `serverless deploy` and corresponding `--stage` flag

This initial deploy may take a few minutes as the first CloudFormation template creates the requisite resources in correct order. Future deploys will be quicker thanks to both serverless and CloudFormation's approach to updates based on diffs.

## Getting help/logging issues

Any issues that arise during deploy should be considered and addressed. Please raise an issue/bug for your use case. The community of Frigg adopters (and serverless.com framework adopters more broadly) are very likely to have run into the same specific issue before.


# Cooking with Frigg

As any well studied practictioner knows- you can train all you want, but checklists and guides are critical to have on hand to keep your practice fresh and make sure you don't miss a step. Our How To guides are intended to take your hard won integration development knowledge, and show you how to use it to solve a variety of problems and use cases.

Our first set of guides are focused on some of the core tricky parts of Frigg.


# The "Why" of Frigg Technical Decisions

Years of integration development on Frigg and proto Frigg have sharpened our opinions for how we developed what we did. Well documented decisions are the goal for Frigg now and going forward. This section will contain those decisions, and any discussion about *why* we built things the way we did. Conversely, it is also an open invite for disagreement and to change our collective minds.


# Core Concepts

Understanding these core concepts will help you get the most out of the Frigg framework:

## Integration

**Extends `@friggframework/integration-base`.**\
An "integration" is how Frigg connects (usually 2) modules for the connection of data and actions. Each service has its own API Module to represent its API to the middleware; use case-specific business logic will also be required.

## API Module

**Composed of an API Class (generally extending a subclass of `@friggframework/requester`) and a Module Definition.**\
The API Class handles the requests to external APIs, i.e. authentication, identification, and data retrieval. The Module Definition lets the @friggframework know how to use this API Class as an API Module, such that tokens and other metadata the connection to an external api, can be stored (and refreshed).

## Entity (authorizing entity)

**A mongoose model extending `@friggframework/module-plugin/entity`:**\
For a given API Module, the entity is a kind of handle, linking to the relevant credentials, and storing metadata about who/what is authorizing. Retrieving these for a given user is an important gateway to accessing an integration, as most integration actions require one or more authorized API Modules. Most generally, an API Module will be instantiated by passing in an Entity.

## Credential

**A mongoose model extending `@friggframework/module-plugin/credential`:**\
For a given API Module, the credential generally stores the tokens or data necessary for making authenticated requests. Multiple Entities can reference the same credential, although 1:1:1 User:Entity:Credential is common.

## Data Handling

Frigg manages data securely and efficiently, ensuring it can scale as needed without compromising performance.

## Customization

Frigg is highly customizable, letting you tailor modules and integrations to fit your specific needs.

## Testing

Frigg supports automated testing with tools like Jest to maintain reliability and performance.

## Contribution

Frigg is open-source and thrives on community contributions. Whether you're fixing bugs, writing documentation, or developing new modules, your input is valuable. We encourage users to get involved through our GitHub repository, participate in discussions, and submit pull requests. Every bit of help makes Frigg better for everyone.


# API Module Definition and Functions

#### Module Definition

```javascript
const API = require('./api');
const authDef = {
    API: API,
    getName: function() {return config.name},
	   moduleName: config.name,
    requiredAuthMethods: {
        // oauth methods
        getToken: async function(api, params) {},
        // for all Auth methods
	 apiPropertiesToPersist: {
            credential: ['access_token', 'refresh_token'],
            entity: []
        },
        getCredentialDetails: async function(api) {}, 
        getEntityDetails: async function(api, callbackParams, tokenResponse, userId) {},
        testAuthRequest: async function() {}, // basic request to testAuth
    },
    env: {
        client_id: process.env.HUBSPOT_CLIENT_ID,
        client_secret: process.env.HUBSPOT_CLIENT_SECRET,
        scope: process.env.HUBSPOT_SCOPE,
        redirect_uri: `${process.env.REDIRECT_URI}/an-api`,
    }
};
```

#### getToken

For OAuth2, this function typically looks like this:

```javascript
const code = get(params.data, 'code'); 
 await api.getTokenFromCode(code);
```

The `getTokenFromCode` method will make the token request and set the token on the API class.

#### apiPropertiesToPersist

Named arrays of properties to persist on either the entity or credential. Upon API class instantiation, these will be retrieved from the entity/credential and passed into the API class. Typically, the entity won't need to store anything, and the credential will suffice to persist tokens and other connection metadata.

#### getEntityDetails

Retrieve and return details about the user/organization that is authorizing requests to this API. Should return something like:

```javascript
 const userDetails = await api.getUserDetails();
return {
        identifiers: { externalId: userDetails.portalId, user: api.userId },
        details: { name: userDetails.hub_domain },
}
```

The identifiers define the uniqueness of the entity and how it is looked up. It will automatically be linked to the created credential.

#### getCredentialDetails

Similar to `getEntityDetails`, returns:

```javascript
 const userDetails = await api.getUserDetails();
return {
        identifiers: { externalId: userDetails.portalId },
        details: {}
};
```

Generally, the entity is looked up first, and the credential is found through that reference.

***

{% hint style="info" %}
The entity and credential details functions require the most knowledge of Frigg Framework, and a deeper understanding of how authentication is handled by the external API. In the case where the external API has user accounts, and tokens per user (vs app or organization tokens), the `externalId` should likely be the user's id in that system (or their email, or whatever unique info can be retrieved).
{% endhint %}


# Architecture

* Backend
* Frontend
* Database
* Eventing
  * Polling Triggers
  * Webhooks
  * Queues
  * Scheduled Tasks
  * User Interaction (API Route)
  * Other
* Logging
* Retry
* Error Handling


# Data Model

Frigg has a fairly straightforward data model

![Frigg Data Model](/files/mXHUKfW0vFJFzKILVBqa)

* Currently we connect to a MongoDB cluster using Mongoose. Recommendation is MongoDB Atlas, fast and free to spin up a test cluster.
* Follow instructions to create
* Copy and paste yours to the `config/dev.json` file


# API Reference

Management API

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/authorize" method="get" expanded="false" fullWidth="false" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/authorize" method="post" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/entities/options/{credentialId}" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/entities" method="post" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations" method="post" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/options" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/{integrationId}" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/{integrationId}" method="delete" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/{integrationId}" method="patch" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/{integrationId}/config/options" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/{integrationId}/actions/{actionId}/options" method="get" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}

{% openapi src="/files/LhgSQr7lznrwiKapijNH" path="/api/integrations/65bbfe8e4124ba1e42b939e4/actions/DELETE\_ALL\_CUSTOM\_OBJECTS" method="post" %}
[Frigg Management API.yml](https://2964746722-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv6ytFIpa5yAaFo1qBpRJ%2Fuploads%2Fgit-blob-dea5765722814bb846f224ec57dcf2ef866173f4%2FFrigg%20Management%20API.yml?alt=media)
{% endopenapi %}


# Overview

API Modules are the Lego bricks that make Frigg-powered integrations develop faster. An API Module is the code that wraps your target partner's API and represents that API back to Frigg.

Frigg's API Modules are available for free under the MIT license. Translation: if your target partner's logo is in this library already, Frigg just saved you many hours of work.

[View our library of v1-ready API Modules](https://github.com/friggframework/api-module-library/tree/main/packages/v1-ready).

Read our [API Module Definition and Functions](/reference/api-module-definition-and-functions) reference doc.


# API Module Library

View and search for all our available API Modules in our [Frigg v1-ready API Module directory](https://github.com/friggframework/api-module-library/tree/main/packages/v1-ready).


# Asana


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Canva Connect


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# ConnectWise PSA

Formerly known as ConnectWise Manage.


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Contentful


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Contentstack


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Deel


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Google Calendar


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Google Drive


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Help Scout

This API Module allows your app to connect to the Help Scout [Mailbox API](https://developer.helpscout.com/mailbox-api/).

### Supported Functionality

* Resource Owner
  * `getUserDetails()`: Gets the resource owner details (/me endpoint)
* Conversations
  * `listConversations()`: Gets the paginated list of conversations
* Customers
  * `listCustomers()`: Gets the paginated list of customers
  * `createCustomer(body)`: Creates a customer
  * `deleteCustomer(id)`: Deletes a customer by ID
* Mailboxes
  * `listMailboxes()`: Gets the paginated list of mailboxes

Please note the Api Module doesn't do any data manipulations. Please refer to the [official documentation](https://developer.helpscout.com/mailbox-api/endpoints/conversations/list/) to look at the exact data shapes.

Looking for more? We love contributions!

* [Here](https://developer.helpscout.com/mailbox-api/endpoints/conversations/list/) you can find the official list of endpoints.
* [Here](https://github.com/friggframework/frigg/blob/v1-alpha/docs/api-module-library/module-list/helpscout/api-module-library/helpscout/README.md) you can find instructions for setting up the integration locally in order to make contributions to the project.


# Configuration

Help Scout has different kinds of apps. The Frigg integration works with the Mailbox API, which allows **your app** to interact with Help Scout in the most flexible way.

### Getting started

This guide assumes you already have a Frigg App working.

1. Sign up/in to your Help Scout account, for free ([site link](https://www.helpscout.com/)).
2. Follow the [official instructions](https://developer.helpscout.com/mailbox-api/overview/authentication/#oauth2-application) for creating an App under your profile (not in the *App Directory*).
3. Specify a Redirection URL that follows this pattern: `https://{your domain}/redirect`. This is an example for localhost: `http://localhost:3000/redirect`.
4. In your Frigg App env file, add the following entries:

```js
"HELPSCOUT_CLIENT_ID": "{{ your app client id }}",
"HELPSCOUT_CLIENT_SECRET": "{{ your app secret }}"
```

5. Add a Help Scout integration file to your Frigg app (you can find an example at the end of this document).
6. Implement any calls you need (use the `getSampleData` method as an example).
7. Add the integration in your appDefinition in `backend.js`:

```js
const appDefinition = {
    integrations: [
        helpscoutIntegration
    ],
    user: {
        password: true,
    }
}
```

8. Done! You are ready to run the app and test the integration live.

### Example integration file

```js
class HelpscoutIntegration extends IntegrationBase {
    static Config = {
        name: 'helpscout',
        version: '1.0.0',
        supportedVersions: ['1.0.0'],
        events: ['EXAMPLE_EVENT'],
    };

    static Options =
        new Options({
            module: HelpscoutModule,
            integrations: [HelpscoutModule],
            display: {
                name: 'Help Scout',
                description: 'Mailbox integration',
                category: 'CRM',
                detailsUrl: 'https://helpscout.com',
                icon: '',
            }
        });

    static display =  {
        name: 'Help Scout',
        description: 'Help Scout Mailbox integration',
        category: 'CRM',
        detailsUrl: 'https://helpscout.com',
        icon: '',
    }

    static modules = {
        helpscout: HelpscoutModule
    }

    /**
     * HANDLE EVENTS
     */
    async receiveNotification(notifier, event, object = null) {

    }

    /**
     * ALL CUSTOM/OPTIONAL METHODS FOR AN INTEGRATION
     */
    async getSampleData() {
        const list = await this.target.api.listConversations()
        
        const formatted = list._embedded.conversations.map(conversation => {
            return {
                id: conversation.id,
                type: conversation.type,
                subject: conversation.subject,
                preview: conversation.preview,
            }
        });
        return { data: formatted }
    }
}
```


# Getting Started


# Supported APIs


# Available Methods


# Hubspot


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Ironclad


# Configuration


# Getting Started


# Supported APIs


# Page


# Linear


# Configuration


# Getting Started


# Supported APIs


# Page


# Microsoft Teams


# Configuration


# Getting Started


# Supported APIs


# Page


# QuickBooks Online

Or as their friends call it, QBO.


# Configuration


# Getting Started


# Supported APIs


# Page


# Salesforce


# Configuration


# Getting Started


# Supported APIs


# Available Methods


# Slack


# Configuration


# Getting Started


# Supported APIs


# Available Methods




---

[Next Page](/llms-full.txt/1)

