Skip to Content

Integration

This guide provides step-by-step instructions on developing an integration for writing external data to AFFiNE Docs.

1. Define integration type

To extend the integration type, simply add an enum to integrationType, which is defined in core/src/modules/db/schema:

// const integrationType = f.enum('readwise'); const integrationType = f.enum("readwise", "newIntegrationType");

2. Define the integration details

You need to provide more details for your integration in core/src/modules/integration/constant.ts, includes:

  • name

    export const INTEGRATION_TYPE_NAME_MAP: Record<IntegrationType, I18nString> = { readwise: 'com.affine.integration.name.readwise', };
  • property schema: Add custom properties to document

    export const INTEGRATION_PROPERTY_SCHEMA: { [T in IntegrationType]: Record<string, IntegrationProperty<T>>; } = { readwise: { author: { order: '400', label: 'com.affine.integration.readwise-prop.author', key: 'author', type: 'text', icon: TextIcon, }, source: { order: '300', label: 'com.affine.integration.readwise-prop.source', key: 'readwise_url', type: 'source', icon: LinkIcon, } }, };
  • icon: A React component

    export const INTEGRATION_ICON_MAP: Record< IntegrationType, React.ComponentType<SVGProps<SVGSVGElement>> > = { readwise: ReadwiseLogoDuotoneIcon, };

3. Create Entity and register it

Create your own entities in core/src/modules/integration/entities

// readwise-crawler.ts export class ReadwiseCrawler extends Entity {} // readwise.ts export class ReadwiseIntegration extends Entity<{ writer: IntegrationWriter }> { writer = this.props.writer; crawler = this.framework.createEntity(ReadwiseCrawler); }

We suggest that divide your entity into XxxIntegration and XxxCrawler

Instant them in core/src/modules/integration/services/integration.ts

export class IntegrationService extends Service { readwise = this.framework.createEntity(ReadwiseIntegration, { writer: this.writer, }); }

Also remember to register in core/src/modules/integration/index.ts

export function configureIntegrationModule(framework: Framework) { framework // ... .entity(ReadwiseCrawler) .entity(ReadwiseIntegration) // ... }

4. Implement your own integration logic and UI

All of your integration logic should be implemented in Entity that just created above. As for writing external metas to AFFiNE Document, the IntegrationWriter would help.

You can access IntegrationWriter in your XxxIntegration entity (you have to implement Entity as above: extends Entity<{ writer: IntegrationWriter }>).

For now we provide a method to transfer markdown string to AFFiNE Document, as well as some additional note or comment: writeDoc(options).

For more detail, please refer to the source code of IntegrationWriter.

Last updated on