Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Create a new service request in Jira Service Management
| `description` | string | No | Description for the service request |
| `raiseOnBehalfOf` | string | No | Account ID of customer to raise request on behalf of |
| `requestFieldValues` | json | No | Request field values as key-value pairs \(overrides summary/description if provided\) |
| `formAnswers` | json | No | Form answers for form-based request types \(e.g., \{"summary": \{"text": "Title"\}, "customfield_10010": \{"choices": \["10320"\]\}\}\) |
| `formAnswers` | json | No | Form answers using numeric form question IDs as keys \(e.g., \{"1": \{"text": "Title"\}, "4": \{"choices": \["5"\]\}\}\). Keys are question IDs from the Jira Form, not Jira field names. |
| `requestParticipants` | string | No | Comma-separated account IDs to add as request participants |
| `channel` | string | No | Channel the request originates from \(e.g., portal, email\) |

Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/en/tools/trello.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Before connecting Trello in Sim, add your Sim app origin to the **Allowed Origin
Trello's authorization flow redirects back to Sim using a `return_url`. If your Sim origin is not whitelisted in Trello, Trello will block the redirect and the connection flow will fail before Sim can save the token.
{/* MANUAL-CONTENT-END */}


Integrate with Trello to list board lists, list cards, create cards, update cards, review activity, and add comments.


Expand Down
2 changes: 1 addition & 1 deletion apps/sim/app/(landing)/integrations/data/integrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -2374,7 +2374,7 @@
"authType": "none",
"category": "tools",
"integrationTypes": ["security", "analytics", "developer-tools"],
"tags": ["monitoring", "security"]
"tags": ["identity", "monitoring"]
},
{
"type": "cursor_v2",
Expand Down
12 changes: 7 additions & 5 deletions apps/sim/app/api/tools/confluence/attachment/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceAttachmentAPI')

Expand Down Expand Up @@ -53,15 +54,16 @@ export async function DELETE(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to delete Confluence attachment (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

return NextResponse.json({ attachmentId, deleted: true })
Expand Down
12 changes: 7 additions & 5 deletions apps/sim/app/api/tools/confluence/attachments/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceAttachmentsAPI')

Expand Down Expand Up @@ -64,15 +65,16 @@ export async function GET(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to list Confluence attachments (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down
56 changes: 35 additions & 21 deletions apps/sim/app/api/tools/confluence/blogposts/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { z } from 'zod'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceBlogPostsAPI')

Expand Down Expand Up @@ -98,14 +99,16 @@ export async function GET(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage = errorData?.message || `Failed to list blog posts (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -197,14 +200,16 @@ export async function POST(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage = errorData?.message || `Failed to create blog post (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -253,14 +258,16 @@ export async function POST(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage = errorData?.message || `Failed to get blog post (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -326,7 +333,10 @@ export async function PUT(request: NextRequest) {
})

if (!currentResponse.ok) {
throw new Error(`Failed to fetch current blog post: ${currentResponse.status}`)
const errorText = await currentResponse.text()
throw new Error(
parseAtlassianErrorMessage(currentResponse.status, currentResponse.statusText, errorText)
)
}

const currentPost = await currentResponse.json()
Expand Down Expand Up @@ -362,14 +372,16 @@ export async function PUT(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage = errorData?.message || `Failed to update blog post (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -426,14 +438,16 @@ export async function DELETE(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage = errorData?.message || `Failed to delete blog post (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

return NextResponse.json({ blogPostId, deleted: true })
Expand Down
28 changes: 17 additions & 11 deletions apps/sim/app/api/tools/confluence/comment/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { z } from 'zod'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceCommentAPI')

Expand Down Expand Up @@ -81,7 +82,10 @@ export async function PUT(request: NextRequest) {
})

if (!getResponse.ok) {
throw new Error(`Failed to fetch current comment: ${getResponse.status}`)
const errorText = await getResponse.text()
throw new Error(
parseAtlassianErrorMessage(getResponse.status, getResponse.statusText, errorText)
)
}

const currentComment = await getResponse.json()
Expand Down Expand Up @@ -111,15 +115,16 @@ export async function PUT(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to update Confluence comment (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -169,15 +174,16 @@ export async function DELETE(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to delete Confluence comment (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

return NextResponse.json({ commentId, deleted: true })
Expand Down
23 changes: 13 additions & 10 deletions apps/sim/app/api/tools/confluence/comments/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceCommentsAPI')

Expand Down Expand Up @@ -69,15 +70,16 @@ export async function POST(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to create Confluence comment (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down Expand Up @@ -149,15 +151,16 @@ export async function GET(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})
const errorMessage =
errorData?.message || `Failed to list Confluence comments (${response.status})`
return NextResponse.json({ error: errorMessage }, { status: response.status })
return NextResponse.json(
{ error: parseAtlassianErrorMessage(response.status, response.statusText, errorText) },
{ status: response.status }
)
}

const data = await response.json()
Expand Down
25 changes: 6 additions & 19 deletions apps/sim/app/api/tools/confluence/create-page/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type NextRequest, NextResponse } from 'next/server'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { validateAlphanumericId, validateJiraCloudId } from '@/lib/core/security/input-validation'
import { getConfluenceCloudId } from '@/tools/confluence/utils'
import { parseAtlassianErrorMessage } from '@/tools/jira/utils'

const logger = createLogger('ConfluenceCreatePageAPI')

Expand Down Expand Up @@ -101,30 +102,16 @@ export async function POST(request: NextRequest) {
})

if (!response.ok) {
const errorData = await response.json().catch(() => null)
const errorText = await response.text()
logger.error('Confluence API error response:', {
status: response.status,
statusText: response.statusText,
error: JSON.stringify(errorData, null, 2),
error: errorText,
})

let errorMessage = `Failed to create Confluence page (${response.status})`
if (errorData?.message) {
errorMessage = errorData.message
} else if (errorData?.errors && Array.isArray(errorData.errors)) {
const firstError = errorData.errors[0]
if (firstError?.title) {
if (firstError.title.includes("'spaceId'") && firstError.title.includes('Long')) {
errorMessage =
'Invalid Space ID. Use the list spaces operation to find valid space IDs.'
} else {
errorMessage = firstError.title
}
} else {
errorMessage = JSON.stringify(errorData.errors)
}
let errorMessage = parseAtlassianErrorMessage(response.status, response.statusText, errorText)
if (errorMessage.includes("'spaceId'") && errorMessage.includes('Long')) {
errorMessage = 'Invalid Space ID. Use the list spaces operation to find valid space IDs.'
}

return NextResponse.json({ error: errorMessage }, { status: response.status })
}

Expand Down
Loading
Loading