130 lines
3.5 KiB
TypeScript
130 lines
3.5 KiB
TypeScript
import { getMetaClientCredentials } from '../../misc/auth'
|
|
import { FeedChanges, FeedChange, CommentChangeValue } from '../../misc/types'
|
|
import { getErrorFromUnknown } from '../../misc/utils'
|
|
import * as bp from '.botpress'
|
|
|
|
export const handler = async (changes: FeedChanges, props: bp.HandlerProps) => {
|
|
if (props.ctx.configurationType === 'sandbox') {
|
|
props.logger.error(
|
|
'Feed changes are not supported in sandbox mode, turn off webhook subscriptions in the Sandbox Meta App'
|
|
)
|
|
return
|
|
}
|
|
|
|
for (const change of changes) {
|
|
await _handleFeedChange(change, props)
|
|
}
|
|
}
|
|
|
|
const _handleFeedChange = async (change: FeedChange, props: bp.HandlerProps) => {
|
|
const { logger } = props
|
|
const { value } = change
|
|
|
|
try {
|
|
switch (value.item) {
|
|
case 'comment':
|
|
await _handleCommentEvent(value, props)
|
|
break
|
|
default:
|
|
logger.forBot().warn(`Unhandled event item: ${value.item}`)
|
|
}
|
|
} catch (error) {
|
|
const errorMsg = getErrorFromUnknown(error)
|
|
logger.forBot().error(`Error processing feed change: ${errorMsg.message}`)
|
|
}
|
|
}
|
|
|
|
const _handleCommentEvent = async (value: CommentChangeValue, props: bp.HandlerProps) => {
|
|
const { logger, ctx, client } = props
|
|
const { from, verb } = value
|
|
const { pageId } = await getMetaClientCredentials({ client, ctx })
|
|
if (!pageId) {
|
|
logger.forBot().error('Page ID is not set, cannot process comment event. Please configure or reauthorize')
|
|
return
|
|
}
|
|
|
|
if (from?.id === pageId) {
|
|
logger.forBot().debug('Comment is from our page, ignoring')
|
|
return
|
|
}
|
|
|
|
logger.forBot().debug(`Processing comment event: verb=${verb} `)
|
|
|
|
switch (verb) {
|
|
case 'add':
|
|
await _handleCommentCreated(value, props)
|
|
break
|
|
case 'remove': // For removed comments
|
|
break
|
|
case 'edited': // For edited comments
|
|
break
|
|
default:
|
|
}
|
|
}
|
|
|
|
const _handleCommentCreated = async (value: CommentChangeValue, props: bp.HandlerProps) => {
|
|
const { client, logger, ctx } = props
|
|
|
|
if (ctx.configurationType === 'sandbox') {
|
|
logger.forBot().error('Comment replies are not supported in sandbox mode')
|
|
return
|
|
}
|
|
|
|
if (!ctx.configuration.replyToComments) {
|
|
logger.forBot().info('Comment replies are disabled in the configuration')
|
|
return
|
|
}
|
|
|
|
const { comment_id: commentId, post_id: postId, message, from, parent_id: parentId } = value
|
|
|
|
if (!message) {
|
|
logger
|
|
.forBot()
|
|
.warn(
|
|
'Incoming comment has no message, will not reply. Make sure that your app has been granted the necessary permissions to access user data.'
|
|
)
|
|
return
|
|
}
|
|
|
|
if (postId !== parentId) {
|
|
logger.forBot().debug('Incoming comment is not a root comment, will not reply')
|
|
return
|
|
}
|
|
|
|
if (!from) {
|
|
logger.forBot().error("Incoming comment doesn't contain 'from' information, will not reply")
|
|
return
|
|
}
|
|
|
|
// Use the thread resolver to create conversation based on root thread ID
|
|
const userId = from.id
|
|
const { conversation } = await client.getOrCreateConversation({
|
|
channel: 'commentReplies',
|
|
tags: { id: commentId, postId, userId },
|
|
discriminateByTags: ['id'],
|
|
})
|
|
|
|
const { user } = await client.getOrCreateUser({
|
|
tags: { id: userId },
|
|
})
|
|
|
|
if (!user.name) {
|
|
await client.updateUser({
|
|
id: user.id,
|
|
name: from.name,
|
|
})
|
|
}
|
|
|
|
await client.getOrCreateMessage({
|
|
tags: {
|
|
id: commentId,
|
|
postId,
|
|
},
|
|
discriminateByTags: ['id'],
|
|
type: 'text',
|
|
payload: { text: message, commentId },
|
|
userId: user.id,
|
|
conversationId: conversation.id,
|
|
})
|
|
}
|