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
21 changes: 21 additions & 0 deletions backend/src/api/eagleEyeContent/eagleEyeContentTrack.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Permissions from '../../security/permissions'
import PermissionChecker from '../../services/user/permissionChecker'
import track from '../../segment/track'

export default async (req, res) => {
new PermissionChecker(req).validateHas(Permissions.values.eagleEyeContentRead)
track(
'Eagle Eye post clicked',
{
url: req.body.url,
platform: req.body.platform,
},
{ ...req },
)

const out = {
Success: true,
}

await req.responseHandler.success(req, res, out)
}
6 changes: 6 additions & 0 deletions backend/src/api/eagleEyeContent/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ export default (app) => {
safeWrap(require('./eagleEyeContentUpsert').default),
)

app.post(
`/tenant/:tenantId/eagleEyeContent/track`,
featureFlagMiddleware(FeatureFlag.EAGLE_EYE, 'entities.eagleEye.errors.planLimitExceeded'),
safeWrap(require('./eagleEyeContentTrack').default),
)

app.get(
`/tenant/:tenantId/eagleEyeContent/search`,
featureFlagMiddleware(FeatureFlag.EAGLE_EYE, 'entities.eagleEye.errors.planLimitExceeded'),
Expand Down
44 changes: 37 additions & 7 deletions backend/src/services/eagleEyeActionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Error404 from '../errors/Error404'
import { EagleEyeAction, EagleEyeActionType } from '../types/eagleEyeTypes'
import { IServiceOptions } from './IServiceOptions'
import { LoggingBase } from './loggingBase'
import track from '../segment/track'

export default class EagleEyeActionService extends LoggingBase {
options: IServiceOptions
Expand All @@ -27,6 +28,18 @@ export default class EagleEyeActionService extends LoggingBase {
throw new Error404(this.options.language, 'errors.eagleEye.contentNotFound')
}

// Tracking here so we have access to url and platform
track(
`Eagle Eye post ${data.type === EagleEyeActionType.BOOKMARK ? 'bookmarked' : 'voted'}`,
{
type: data.type,
url: content.url,
platform: content.platform,
action: 'create',
},
{ ...this.options },
)

const existingUserActions: EagleEyeAction[] = content.actions.filter(
(a) => a.actionById === this.options.currentUser.id,
)
Expand All @@ -50,7 +63,10 @@ export default class EagleEyeActionService extends LoggingBase {
await EagleEyeActionRepository.removeActionFromContent(
EagleEyeActionType.THUMBS_UP,
contentId,
this.options,
{
...this.options,
transaction,
},
)
} else if (
data.type === EagleEyeActionType.THUMBS_UP &&
Expand All @@ -59,16 +75,18 @@ export default class EagleEyeActionService extends LoggingBase {
await EagleEyeActionRepository.removeActionFromContent(
EagleEyeActionType.THUMBS_DOWN,
contentId,
this.options,
{
...this.options,
transaction,
},
)
}

// add new action
const record = await EagleEyeActionRepository.createActionForContent(
data,
contentId,
this.options,
)
const record = await EagleEyeActionRepository.createActionForContent(data, contentId, {
...this.options,
transaction,
})

await SequelizeRepository.commitTransaction(transaction)

Expand Down Expand Up @@ -96,5 +114,17 @@ export default class EagleEyeActionService extends LoggingBase {
if (content.actions.length === 0) {
await EagleEyeContentRepository.destroy(contentId, this.options)
}

// Tracking here so we have access to url and platform
track(
`Eagle Eye post ${action.type === EagleEyeActionType.BOOKMARK ? 'bookmarked' : 'voted'}`,
{
type: action.type,
url: content.url,
platform: content.platform,
action: 'destroy',
},
{ ...this.options },
)
}
}
36 changes: 36 additions & 0 deletions backend/src/services/eagleEyeSettingsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import lodash from 'lodash'
import SequelizeRepository from '../database/repositories/sequelizeRepository'
import UserRepository from '../database/repositories/userRepository'
import Error400 from '../errors/Error400'
import track from '../segment/track'
import {
EagleEyeSettings,
EagleEyeFeedSettings,
Expand Down Expand Up @@ -146,6 +147,41 @@ export default class EagleEyeSettingsService extends LoggingBase {

await SequelizeRepository.commitTransaction(transaction)

// Track the events in Segment
const settingsOut: EagleEyeSettings = userOut.eagleEyeSettings

if (data.emailDigestActive) {
track(
'Eagle Eye email settings updated',
{
email: settingsOut.emailDigest.email,
frequency: settingsOut.emailDigest.frequency,
time: settingsOut.emailDigest.time,
matchFeedSettings: settingsOut.emailDigest.matchFeedSettings,
platforms: settingsOut.emailDigest.feed.platforms,
publishedDate: settingsOut.emailDigest.feed.publishedDate,
keywords: settingsOut.emailDigest.feed.keywords,
exactKeywords: settingsOut.emailDigest.feed.exactKeywords,
excludeKeywords: settingsOut.emailDigest.feed.excludedKeywords,
},
{ ...this.options },
)
} else {
track(
'Eagle Eye settings updated',
{
onboarded: settingsOut.onboarded,
emailDigestActive: settingsOut.emailDigestActive,
platforms: settingsOut.feed.platforms,
publishedDate: settingsOut.feed.publishedDate,
keywords: settingsOut.feed.keywords,
exactKeywords: settingsOut.feed.exactKeywords,
excludeKeywords: settingsOut.feed.excludedKeywords,
},
{ ...this.options },
)
}

return userOut.eagleEyeSettings
} catch (error) {
await SequelizeRepository.rollbackTransaction(transaction)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import RedisPubSubEmitter from '../../../utils/redis/pubSubEmitter'
import { createRedisClient } from '../../../utils/redis'
import { ApiWebsocketMessage } from '../../../types/mq/apiWebsocketMessage'
import MemberEnrichmentCacheRepository from '../../../database/repositories/memberEnrichmentCacheRepository'
import track from '../../../segment/telemetryTrack'
import track from '../../../segment/track'

export default class MemberEnrichmentService extends LoggingBase {
options: IServiceOptions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@
import { formatDateToTimeAgo } from '@/utils/date'
import { computed, defineProps } from 'vue'
import platformOptions from '@/premium/eagle-eye/constants/eagle-eye-platforms.json'
import { EagleEyeService } from '../../eagle-eye-service'
import { withHttp } from '@/utils/string'
import {
mapActions,
Expand Down Expand Up @@ -217,12 +218,17 @@ const bookmarkTooltip = computed(() => {
})

// Open post in origin url
const onCardClick = (e) => {
const onCardClick = async (e) => {
if (!props.result.url || e.target.localName === 'a') {
return
}

window.open(withHttp(props.result.url), '_blank')

await EagleEyeService.trackClick({
url: props.result.url,
platform: props.result.platform
})
}

// If opposite thumbs up is set, remove before creating the new action
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/premium/eagle-eye/eagle-eye-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ export class EagleEyeService {
return response.data
}

static async trackClick({ url, platform }) {
const tenantId = AuthCurrentTenant.get()
const response = await authAxios.post(
`/tenant/${tenantId}/eagleEyeContent/track`,
{
url,
platform
}
)
return response.data
}

static async addAction({ postId, actionData }) {
const tenantId = AuthCurrentTenant.get()

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/premium/eagle-eye/pages/eagle-eye-page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import AppEagleEyeSettings from '@/premium/eagle-eye/components/list/eagle-eye-s
import AppEagleEyeList from '@/premium/eagle-eye/components/list/eagle-eye-list.vue'
import AppEagleEyeLoadingState from '@/premium/eagle-eye/components/list/eagle-eye-loading-state.vue'
import { mapGetters } from '@/shared/vuex/vuex.helpers'
import { computed, onMounted } from 'vue'
import { computed, onMounted } from 'vue'
import { useStore } from 'vuex'

const { showBanner } = mapGetters('tenant')
Expand Down