# Create Google Drive Feed

## Feed: Create Google Drive Feed

### User Intent

"I want to sync my Google Drive files into Graphlit for search and AI interactions"

### Operation

* **SDK Method**: `graphlit.createFeed()` with Google Drive configuration
* **GraphQL**: `createFeed` mutation
* **Entity Type**: Feed
* **Common Use Cases**: Google Drive sync, document search, file monitoring, team knowledge base

### TypeScript (Canonical)

```typescript
import { Graphlit } from 'graphlit-client';
import {
  ContentTypes,
  FeedInput,
  FeedServiceTypes,
  FeedTypes,
  FileTypes,
  SearchTypes,
} from 'graphlit-client/dist/generated/graphql-types';

const graphlit = new Graphlit();

// Create Google Drive feed
const feedInput: FeedInput = {
  name: 'Company Google Drive',
  type: FeedTypes.Site,
  site: {
    type: FeedServiceTypes.GoogleDrive,
    googleDrive: {
      refreshToken: process.env.GOOGLE_REFRESH_TOKEN!,
      folderIds: ['folder-id'],
      includeFiles: true,
    },
  },
};

const response = await graphlit.createFeed(feedInput);
const feedId = response.createFeed.id;

console.log(`Google Drive feed created: ${feedId}`);

// Poll for initial sync completion
while (true) {
  const status = await graphlit.isFeedDone(feedId);
  if (status.isFeedDone.result) {
    break;
  }
  console.log('Still syncing Google Drive files...');
  await new Promise((resolve) => setTimeout(resolve, 10_000));
}

console.log('Google Drive feed sync complete!');

// Query synced files
const files = await graphlit.queryContents({
  feeds: [{ id: feedId }],
  types: [ContentTypes.File],
});

console.log(`Synced ${files.contents.results.length} files from Google Drive`);
```

## Create feed (snake\_case)

feed\_input = FeedInput( name="Company Google Drive", type=FeedTypes.Site, site=SiteFeedPropertiesInput( type=FeedServiceTypes.GoogleDrive, include\_files=True, folder\_ids=\["folder-id-1", "folder-id-2"], refresh\_token=os.environ\["GOOGLE\_REFRESH\_TOKEN"] ) )

response = await graphlit.createFeed(feed\_input) feed\_id = response.createFeed.id

## Poll for completion

is\_done = False while not is\_done: status = await graphlit.isFeedDone(feed\_id) is\_done = status.isFeedDone.result if status.isFeedDone else False

```
if not is_done:
    await asyncio.sleep(10)
```

````

**C#**:
```csharp
using Graphlit;

var client = new Graphlit();

// Create feed (PascalCase)
var feedInput = new FeedInput {
    Name = "Company Google Drive",
    Type = FeedGoogle,
    Google = new GoogleFeedPropertiesInput {
        Type = FeedServiceTypes.GoogleDrive,
        IncludeFiles = true,
        FolderIds = new[] { "folder-id-1", "folder-id-2" },
        RefreshToken = Environment.GetEnvironmentVariable("GOOGLE_REFRESH_TOKEN")
    }
};

var response = await graphlit.CreateFeed(feedInput);
var feedId = response.CreateFeed.Id;

// Poll for completion
bool isDone = false;
while (!isDone)
{
    var status = await graphlit.IsFeedDone(feedId);
    isDone = status.IsFeedDone?.Result ?? false;
    
    if (!isDone)
    {
        await Task.Delay(10000);
    }
}
````

### Parameters

#### FeedInput (Required)

* **`name`** (string): Feed name
* **`type`** (FeedTypes): Must be `GOOGLE`
* **`google`** (GoogleFeedPropertiesInput): Google Drive configuration

#### GoogleFeedPropertiesInput (Required)

* **`type`** (FeedServiceTypes): Must be `GOOGLE_DRIVE`
* **`refreshToken`** (string): Google OAuth refresh token
  * Requires Google Drive API access
  * Scopes: `https://www.googleapis.com/auth/drive.readonly`
* **`includeFiles`** (boolean): Sync files (recommended: true)
* **`folderIds`** (string\[]): Specific folders to sync
  * Empty array = sync entire drive (not recommended for large drives)
  * Get folder IDs from Google Drive URLs

#### Optional

* **`correlationId`** (string): For tracking
* **`collections`** (EntityReferenceInput\[]): Auto-add files to collections
* **`workflow`** (EntityReferenceInput): Apply workflow to files

### Response

```typescript
{
  createFeed: {
    id: string;                  // Feed ID
    name: string;                // Feed name
    state: EntityState;          // ENABLED
    type: FeedTypes.Site;      // SITE (Google Drive)
    google: {
      type: FeedServiceTypes.GoogleDrive;
      includeFiles: boolean;
      folderIds: string[];
    }
  }
}
```

### Developer Hints

#### OAuth Refresh Token Required

**Getting Google OAuth Token**:

1. Create Google Cloud project at <https://console.cloud.google.com>
2. Enable Google Drive API
3. Create OAuth 2.0 credentials
4. Required scope: `https://www.googleapis.com/auth/drive.readonly`
5. Exchange authorization code for refresh token
6. Store refresh token securely

```typescript
// Refresh token is loaded from environment
const refreshToken = process.env.GOOGLE_REFRESH_TOKEN!; 
// Actual format: '1//0abcd...' (long alphanumeric string)
```

**Important**: Never commit refresh tokens to source control.

#### Folder ID Discovery

**Getting Folder IDs**:

```
// Google Drive URL format:
https://drive.google.com/drive/folders/FOLDER_ID_HERE

// Extract FOLDER_ID_HERE
```

**Example**:

```
URL: https://drive.google.com/drive/folders/1A2B3C4D5E6F7G8H9
Folder ID: 1A2B3C4D5E6F7G8H9
```

#### File Type Filtering

```typescript
// After sync, query specific file types
const pdfs = await graphlit.queryContents({
  feeds: [{ id: feedId }],
  fileTypes: [FileTypes.Pdf]
});

const docs = await graphlit.queryContents({
  feeds: [{ id: feedId }],
  fileTypes: [FileTypes.Document]  // Word docs
});
```

#### Continuous Sync

```typescript
// Feed continuously monitors for changes
const feed = await graphlit.createFeed(feedInput);

// New/updated files sync automatically
// No manual refresh needed
```

**Important**: Feeds run continuously. To stop syncing, disable or delete the feed.

### Variations

#### 1. Sync Entire Drive

Sync all files (use carefully):

```typescript
const feedInput: FeedInput = {
  name: 'Full Google Drive',
  type: FeedTypes.Site,
  google: {
    type: FeedServiceTypes.GoogleDrive,
    includeFiles: true,
    folderIds: [],  // Empty = entire drive
    refreshToken: googleToken
  }
};
```

#### 2. Sync Specific Folders

Target specific folders:

```typescript
const feedInput: FeedInput = {
  name: 'Engineering Docs',
  type: FeedTypes.Site,
  google: {
    type: FeedServiceTypes.GoogleDrive,
    includeFiles: true,
    folderIds: [
      '1A2B3C4D5E',  // Engineering folder
      '9Z8Y7X6W5V'   // Architecture folder
    ],
    refreshToken: googleToken
  }
};
```

#### 3. Sync with Auto-Collection

Add files to collection automatically:

```typescript
// Create collection
const collection = await graphlit.createCollection({
  name: 'Google Drive Files'
});

// Create feed with collection
const feedInput: FeedInput = {
  name: 'Drive to Collection',
  type: FeedTypes.Site,
  google: {
    type: FeedServiceTypes.GoogleDrive,
    includeFiles: true,
    folderIds: folderIds,
    refreshToken: googleToken
  },
  collections: [{ id: collection.createCollection.id }]
};
```

#### 4. Sync with Workflow

Apply preparation workflow to files:

```typescript
// Create workflow for PDF extraction
const workflow = await graphlit.createWorkflow({
  name: 'PDF Preparation',
  preparation: {
    jobs: [{
      connector: {
        type: FilePreparationServiceTypes.ModelDocument,
        modelDocument: {
          specification: { id: visionSpecId }
        }
      }
    }]
  }
});

// Create feed with workflow
const feedInput: FeedInput = {
  name: 'Drive with Workflow',
  type: FeedTypes.Site,
  google: {
    type: FeedServiceTypes.GoogleDrive,
    includeFiles: true,
    folderIds: folderIds,
    refreshToken: googleToken
  },
  workflow: { id: workflow.createWorkflow.id }
};
```

#### 5. Team-Specific Feeds

Create feeds per team:

```typescript
const teams = {
  engineering: {
    folderId: '1A2B3C4D5E',
    feedName: 'Engineering Drive'
  },
  product: {
    folderId: '9Z8Y7X6W5V',
    feedName: 'Product Drive'
  },
  sales: {
    folderId: '5T4R3E2W1Q',
    feedName: 'Sales Drive'
  }
};

// Create feed for each team
for (const [team, config] of Object.entries(teams)) {
  const feed = await graphlit.createFeed({
    name: config.feedName,
    type: FeedTypes.Site,
    google: {
      type: FeedServiceTypes.GoogleDrive,
      includeFiles: true,
      folderIds: [config.folderId],
      refreshToken: googleToken
    }
  });
  
  console.log(`Created ${team} feed: ${feed.createFeed.id}`);
}
```

#### 6. Query Synced Files

Search through synced Google Drive files:

```typescript
// After feed sync completes
const results = await graphlit.queryContents({
  feeds: [{ id: feedId }],
  search: 'quarterly report',
  searchType: SearchTypes.Hybrid,
  fileTypes: [FileTypes.Pdf, FileTypes.Document]
});

results.contents.results.forEach(file => {
  console.log(`${file.name} - ${file.fileType}`);
});
```

### Common Issues

**Issue**: `Invalid token` error\
**Solution**: Refresh token expired or invalid. Re-authenticate and get new refresh token. Ensure correct Google Drive API scopes.

**Issue**: No files syncing\
**Solution**: Check `includeFiles: true` is set. Verify folder IDs are correct. Check OAuth token has Drive access.

**Issue**: `Folder not found` error\
**Solution**: Verify folder IDs from Drive URLs. Ensure OAuth account has access to folders.

**Issue**: Feed syncs slowly\
**Solution**: This is normal for large folders. Use `isFeedDone()` to poll. Initial sync can take 10-30 minutes for hundreds of files.

**Issue**: Some files missing\
**Solution**: Check file permissions. OAuth account must have read access to all files in folder.

### Production Example

**Complete Google Drive sync pipeline**:

```typescript
// 1. Get OAuth refresh token (one-time setup)
const refreshToken = await getGoogleRefreshToken(); // Your OAuth flow

// 2. Create collection for organization
const collection = await graphlit.createCollection({
  name: 'Company Documents'
});

// 3. Create preparation workflow
const workflow = await graphlit.createWorkflow({
  name: 'Document Prep',
  preparation: {
    jobs: [{
      connector: {
        type: FilePreparationServiceTypes.ModelDocument,
        modelDocument: {
          specification: { id: visionSpecId }
        }
      }
    }]
  }
});

// 4. Create Google Drive feed
const feed = await graphlit.createFeed({
  name: 'Company Google Drive',
  type: FeedTypes.Site,
  google: {
    type: FeedServiceTypes.GoogleDrive,
    includeFiles: true,
    folderIds: ['root-folder-id'],
    refreshToken: refreshToken
  },
  collections: [{ id: collection.createCollection.id }],
  workflow: { id: workflow.createWorkflow.id }
});

// 5. Wait for initial sync
const feedId = feed.createFeed.id;
let isDone = false;

while (!isDone) {
  const status = await graphlit.isFeedDone(feedId);
  isDone = status.isFeedDone.result || false;
  
  if (!isDone) {
    // Check progress
    const synced = await graphlit.queryContents({ feeds: [{ id: feedId }] });
    console.log(`Synced ${synced.contents.results.length} files so far...`);
    await new Promise(resolve => setTimeout(resolve, 30000)); // 30 sec
  }
}

console.log(' Google Drive sync complete');

// 6. Enable RAG queries
const answer = await graphlit.promptConversation({
  prompt: 'Summarize our Q4 strategy',
  collections: [{ id: collection.createCollection.id }]
});

console.log(answer.message.message);
```

**Multi-folder organization**:

```typescript
// Sync multiple team folders into separate collections
const teams = [
  { name: 'Engineering', folderId: '1A2B3C4D' },
  { name: 'Product', folderId: '5E6F7G8H' },
  { name: 'Sales', folderId: '9I0J1K2L' }
];

for (const team of teams) {
  // Create collection per team
  const collection = await graphlit.createCollection({
    name: `${team.name} Drive`
  });
  
  // Create feed for team folder
  await graphlit.createFeed({
    name: `${team.name} Google Drive`,
    type: FeedTypes.Site,
    google: {
      type: FeedServiceTypes.GoogleDrive,
      includeFiles: true,
      folderIds: [team.folderId],
      refreshToken: googleToken
    },
    collections: [{ id: collection.createCollection.id }]
  });
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.graphlit.dev/api-guides/use-cases/feeds/cloud-storage/feed-create-google-drive.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
