# Microsoft OAuth

Connect Outlook Mail, OneDrive, Calendar, and Contacts to your workflows.

JsWorkflows provides a platform-managed Microsoft OAuth app. You do not need to register an Azure application or provide credentials.

## Available scopes

| Resource | Operation | Scope |
| --- | --- | --- |
| Outlook Mail | Read mail | `Mail.Read` |
| Outlook Mail | Send mail | `Mail.Send` |
| Outlook Mail | Read & write mail | `Mail.ReadWrite`, `Mail.Send` |
| OneDrive | Read files | `Files.Read` |
| OneDrive | Read & write files | `Files.ReadWrite` |
| Outlook Calendar | Read calendar | `Calendars.Read` |
| Outlook Calendar | Read & write calendar | `Calendars.ReadWrite` |
| Outlook Contacts | Read contacts | `Contacts.Read` |
| Outlook Contacts | Read & write contacts | `Contacts.ReadWrite` |
| User Profile | Read profile | `User.Read` |

## Connecting

1. Go to **OAuth Connections → Add Connection → Microsoft**.
2. Select the resources and operations your workflow needs.
3. Sign in with your Microsoft account and grant the requested permissions.
4. Give the connection a handle (e.g., `my-microsoft`).

Use lowercase letters, numbers, and hyphens only for the handle.

Access tokens are refreshed automatically when they expire.

## Example: send an email via Outlook

```js
export class Workflow {
  async start(data, _headers, api) {
    const { token, error } = await api.getOAuthToken('my-microsoft');
    if (error || !token) throw new Error(error || 'Missing Microsoft token');

    const response = await fetch('https://graph.microsoft.com/v1.0/me/sendMail', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json; charset=utf-8',
        Authorization: `Bearer ${token}`,
      },
      body: JSON.stringify({
        message: {
          subject: `Order ${data.name} confirmed`,
          body: { contentType: 'Text', content: `Thank you for your order of ${data.total_price} ${data.currency}.` },
          toRecipients: [{ emailAddress: { address: data.email } }],
        },
        saveToSentItems: false,
      }),
    });

    if (!response.ok) {
      throw new Error(`Microsoft Graph ${response.status}: ${await response.text()}`);
    }
  }
}
```

`sendMail` returns `202 Accepted` with no response body on success.

## Example: upload a file to OneDrive

```js
const { token, error } = await api.getOAuthToken('my-microsoft');
if (error || !token) throw new Error(error || 'Missing Microsoft token');

const csvString = 'order,amount\\n1001,49.95\\n';
const fileBytes = new TextEncoder().encode(csvString);

const response = await fetch('https://graph.microsoft.com/v1.0/me/drive/root:/reports/orders.csv:/content', {
  method: 'PUT',
  headers: {
    'Content-Type': 'text/csv; charset=utf-8',
    Authorization: `Bearer ${token}`,
  },
  body: fileBytes,
});

if (!response.ok) {
  throw new Error(`Microsoft Graph ${response.status}: ${await response.text()}`);
}

const driveItem = await response.json();
console.log(`Uploaded ${driveItem.name} (${driveItem.size} bytes)`);
```