-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Feat(microsoftteams-file): new trigger + file upload #1590
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
68b5b4e
adding file logic and chat trigger
07fcf04
working trig
7be20de
teams specific logic
3aca1c9
greptile comments
66b4143
lint
a0018ce
cleaned up
e72c9b1
save modal changes
02c4c3c
created a interface for subscriptions
4f91208
removed trigger task
db874e9
reduce comments
08c641f
removed trig task
eec25e6
removed comment
1f57490
simplified
e272836
added tele logic back
9fa0fb7
addressed some more comments
74f7b2f
simplified db call
610d85e
cleaned up utils
d49b120
helper telegram
45d529f
removed fallback
0af2747
removed scope
17807bf
Merge staging to get attachment processing helpers
icecrasher321 ae40a6a
simplify to use helpers
icecrasher321 d7d9f64
fix credential resolution
icecrasher321 6b619cb
add logs
icecrasher321 703af2a
fix
icecrasher321 9b3b4fd
fix attachment case
icecrasher321 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| import { db } from '@sim/db' | ||
| import { webhook as webhookTable, workflow as workflowTable } from '@sim/db/schema' | ||
| import { and, eq } from 'drizzle-orm' | ||
| import { type NextRequest, NextResponse } from 'next/server' | ||
| import { verifyCronAuth } from '@/lib/auth/internal' | ||
| import { createLogger } from '@/lib/logs/console/logger' | ||
| import { refreshAccessTokenIfNeeded } from '@/app/api/auth/oauth/utils' | ||
|
|
||
| const logger = createLogger('TeamsSubscriptionRenewal') | ||
|
|
||
| /** | ||
| * Cron endpoint to renew Microsoft Teams chat subscriptions before they expire | ||
| * | ||
| * Teams subscriptions expire after ~3 days and must be renewed. | ||
| * Configured in helm/sim/values.yaml under cronjobs.jobs.renewSubscriptions | ||
| */ | ||
| export async function GET(request: NextRequest) { | ||
| try { | ||
| const authError = verifyCronAuth(request, 'Teams subscription renewal') | ||
| if (authError) { | ||
| return authError | ||
| } | ||
|
|
||
| logger.info('Starting Teams subscription renewal job') | ||
|
|
||
| let totalRenewed = 0 | ||
| let totalFailed = 0 | ||
| let totalChecked = 0 | ||
|
|
||
| // Get all active Microsoft Teams webhooks with their workflows | ||
| const webhooksWithWorkflows = await db | ||
| .select({ | ||
| webhook: webhookTable, | ||
| workflow: workflowTable, | ||
| }) | ||
| .from(webhookTable) | ||
| .innerJoin(workflowTable, eq(webhookTable.workflowId, workflowTable.id)) | ||
| .where(and(eq(webhookTable.isActive, true), eq(webhookTable.provider, 'microsoftteams'))) | ||
|
|
||
| logger.info( | ||
| `Found ${webhooksWithWorkflows.length} active Teams webhooks, checking for expiring subscriptions` | ||
| ) | ||
|
|
||
| // Renewal threshold: 48 hours before expiration | ||
| const renewalThreshold = new Date(Date.now() + 48 * 60 * 60 * 1000) | ||
|
|
||
| for (const { webhook, workflow } of webhooksWithWorkflows) { | ||
| const config = (webhook.providerConfig as Record<string, any>) || {} | ||
|
|
||
| // Check if this is a Teams chat subscription that needs renewal | ||
| if (config.triggerId !== 'microsoftteams_chat_subscription') continue | ||
|
|
||
| const expirationStr = config.subscriptionExpiration as string | undefined | ||
| if (!expirationStr) continue | ||
|
|
||
| const expiresAt = new Date(expirationStr) | ||
| if (expiresAt > renewalThreshold) continue // Not expiring soon | ||
|
|
||
| totalChecked++ | ||
|
|
||
| try { | ||
| logger.info( | ||
| `Renewing Teams subscription for webhook ${webhook.id} (expires: ${expiresAt.toISOString()})` | ||
| ) | ||
|
|
||
| const credentialId = config.credentialId as string | undefined | ||
| const externalSubscriptionId = config.externalSubscriptionId as string | undefined | ||
|
|
||
| if (!credentialId || !externalSubscriptionId) { | ||
| logger.error(`Missing credentialId or externalSubscriptionId for webhook ${webhook.id}`) | ||
| totalFailed++ | ||
| continue | ||
| } | ||
|
|
||
| // Get fresh access token | ||
| const accessToken = await refreshAccessTokenIfNeeded( | ||
| credentialId, | ||
| workflow.userId, | ||
| `renewal-${webhook.id}` | ||
| ) | ||
|
|
||
| if (!accessToken) { | ||
| logger.error(`Failed to get access token for webhook ${webhook.id}`) | ||
| totalFailed++ | ||
| continue | ||
| } | ||
|
|
||
| // Extend subscription to maximum lifetime (4230 minutes = ~3 days) | ||
| const maxLifetimeMinutes = 4230 | ||
| const newExpirationDateTime = new Date( | ||
| Date.now() + maxLifetimeMinutes * 60 * 1000 | ||
| ).toISOString() | ||
|
|
||
| const res = await fetch( | ||
| `https://graph.microsoft.com/v1.0/subscriptions/${externalSubscriptionId}`, | ||
| { | ||
| method: 'PATCH', | ||
| headers: { | ||
| Authorization: `Bearer ${accessToken}`, | ||
| 'Content-Type': 'application/json', | ||
| }, | ||
| body: JSON.stringify({ expirationDateTime: newExpirationDateTime }), | ||
| } | ||
| ) | ||
|
|
||
| if (!res.ok) { | ||
| const error = await res.json() | ||
| logger.error( | ||
| `Failed to renew Teams subscription ${externalSubscriptionId} for webhook ${webhook.id}`, | ||
| { status: res.status, error: error.error } | ||
| ) | ||
| totalFailed++ | ||
| continue | ||
| } | ||
|
|
||
| const payload = await res.json() | ||
|
|
||
| // Update webhook config with new expiration | ||
| const updatedConfig = { | ||
| ...config, | ||
| subscriptionExpiration: payload.expirationDateTime, | ||
| } | ||
|
|
||
| await db | ||
| .update(webhookTable) | ||
| .set({ providerConfig: updatedConfig, updatedAt: new Date() }) | ||
| .where(eq(webhookTable.id, webhook.id)) | ||
|
|
||
| logger.info( | ||
| `Successfully renewed Teams subscription for webhook ${webhook.id}. New expiration: ${payload.expirationDateTime}` | ||
| ) | ||
| totalRenewed++ | ||
| } catch (error) { | ||
| logger.error(`Error renewing subscription for webhook ${webhook.id}:`, error) | ||
| totalFailed++ | ||
| } | ||
| } | ||
|
|
||
| logger.info( | ||
| `Teams subscription renewal job completed. Checked: ${totalChecked}, Renewed: ${totalRenewed}, Failed: ${totalFailed}` | ||
| ) | ||
|
|
||
| return NextResponse.json({ | ||
| success: true, | ||
| checked: totalChecked, | ||
| renewed: totalRenewed, | ||
| failed: totalFailed, | ||
| total: webhooksWithWorkflows.length, | ||
| }) | ||
| } catch (error) { | ||
| logger.error('Error in Teams subscription renewal job:', error) | ||
| return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use verifyCronAuth (verifyCronSecret)