Skip to content

Commit 296108d

Browse files
committed
Add websocket listener for failed messages
1 parent 79339c5 commit 296108d

3 files changed

Lines changed: 55 additions & 30 deletions

File tree

api/pkg/listeners/websocket_listener.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,50 @@ func NewWebsocketListener(
3232
}
3333

3434
return l, map[string]events.EventListener{
35-
events.EventTypePhoneUpdated: l.onPhoneUpdated,
35+
events.EventTypePhoneUpdated: l.onPhoneUpdated,
36+
events.EventTypeMessagePhoneSent: l.onMessagePhoneSent,
37+
events.EventTypeMessageSendFailed: l.onMessagePhoneFailed,
3638
}
3739
}
3840

41+
// onMessagePhoneSent handles the events.EventTypeMessagePhoneSent event
42+
func (listener *WebsocketListener) onMessagePhoneSent(ctx context.Context, event cloudevents.Event) error {
43+
ctx, span, _ := listener.tracer.StartWithLogger(ctx, listener.logger)
44+
defer span.End()
45+
46+
var payload events.MessagePhoneSentPayload
47+
if err := event.DataAs(&payload); err != nil {
48+
msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
49+
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
50+
}
51+
52+
if err := listener.client.Trigger(payload.UserID.String(), event.Type(), event.ID()); err != nil {
53+
msg := fmt.Sprintf("cannot trigger websocket [%s] event with ID [%s] for user with ID [%s]", event.Type(), event.ID(), payload.UserID)
54+
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
55+
}
56+
57+
return nil
58+
}
59+
60+
// onMessagePhoneFailed handles the events.EventTypeMessageSendFailed event
61+
func (listener *WebsocketListener) onMessagePhoneFailed(ctx context.Context, event cloudevents.Event) error {
62+
ctx, span, _ := listener.tracer.StartWithLogger(ctx, listener.logger)
63+
defer span.End()
64+
65+
var payload events.MessageSendFailedPayload
66+
if err := event.DataAs(&payload); err != nil {
67+
msg := fmt.Sprintf("cannot decode [%s] into [%T]", event.Data(), payload)
68+
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
69+
}
70+
71+
if err := listener.client.Trigger(payload.UserID.String(), event.Type(), event.ID()); err != nil {
72+
msg := fmt.Sprintf("cannot trigger websocket [%s] event with ID [%s] for user with ID [%s]", event.Type(), event.ID(), payload.UserID)
73+
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
74+
}
75+
76+
return nil
77+
}
78+
3979
// onPhoneUpdated handles the events.EventTypePhoneUpdated event
4080
func (listener *WebsocketListener) onPhoneUpdated(ctx context.Context, event cloudevents.Event) error {
4181
ctx, span, _ := listener.tracer.StartWithLogger(ctx, listener.logger)
@@ -47,7 +87,7 @@ func (listener *WebsocketListener) onPhoneUpdated(ctx context.Context, event clo
4787
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
4888
}
4989

50-
if err := listener.client.Trigger(payload.UserID.String(), event.Type(), event); err != nil {
90+
if err := listener.client.Trigger(payload.UserID.String(), event.Type(), event.ID()); err != nil {
5191
msg := fmt.Sprintf("cannot trigger websocket [%s] event with ID [%s] for user with ID [%s]", event.Type(), event.ID(), payload.UserID)
5292
return listener.tracer.WrapErrorSpan(span, stacktrace.Propagate(err, msg))
5393
}

web/layouts/default.vue

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@
2828

2929
<script lang="ts">
3030
import { Vue, Component } from 'vue-property-decorator'
31-
import { mdiBullhorn } from '@mdi/js'
3231
import Pusher from 'pusher-js'
3332
import { setAuthHeader } from '~/plugins/axios'
3433
3534
@Component
3635
export default class DefaultLayout extends Vue {
3736
poller: number | null = null
38-
mdiBullhorn: string = mdiBullhorn
37+
canPoll: boolean = false
3938
4039
get hasDrawer(): boolean {
4140
return ['threads', 'threads-id'].includes(this.$route.name ?? '')
@@ -49,11 +48,17 @@ export default class DefaultLayout extends Vue {
4948
5049
const channel = pusher.subscribe(this.$store.getters.getAuthUser.id)
5150
channel.bind('phone.updated', () => {
52-
this.$store.dispatch('setCanPoll', true)
51+
this.canPoll = true
52+
})
53+
channel.bind('message.phone.sent', () => {
54+
this.canPoll = true
55+
})
56+
channel.bind('message.send.failed', () => {
57+
this.canPoll = true
5358
})
5459
5560
this.startPoller()
56-
}, 5000) // delay so that the auth user is present
61+
}, 10_000) // delay so that the auth user is present
5762
}
5863
5964
beforeDestroy(): void {
@@ -64,10 +69,7 @@ export default class DefaultLayout extends Vue {
6469
6570
startPoller() {
6671
this.poller = window.setInterval(async () => {
67-
if (
68-
!this.$store.getters.getCanPoll ||
69-
this.$store.getters.getAuthUser == null
70-
) {
72+
if (!this.canPoll || this.$store.getters.getAuthUser == null) {
7173
return
7274
}
7375
@@ -81,11 +83,9 @@ export default class DefaultLayout extends Vue {
8183
this.$store.dispatch('getHeartbeat'),
8284
)
8385
}
84-
promises.push(
85-
this.$store.dispatch('loadPhones', true),
86-
this.$store.dispatch('setCanPoll', false),
87-
)
86+
promises.push(this.$store.dispatch('loadPhones', true))
8887
88+
this.canPoll = false
8989
if (this.$store.getters.hasThread) {
9090
promises.push(
9191
this.$store.dispatch(
@@ -99,7 +99,7 @@ export default class DefaultLayout extends Vue {
9999
setTimeout(() => {
100100
this.$store.dispatch('setPolling', false)
101101
}, 1000)
102-
}, 10000)
102+
}, 10_000)
103103
}
104104
}
105105
</script>

web/store/index.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ export type State = {
6969
threadId: string | null
7070
heartbeat: null | Heartbeat
7171
pooling: boolean
72-
canPoll: boolean
7372
notification: Notification
7473
}
7574

@@ -84,7 +83,6 @@ export const state = (): State => ({
8483
billingUsageHistory: [],
8584
archivedThreads: false,
8685
pooling: false,
87-
canPoll: true,
8886
phones: [],
8987
user: null,
9088
owner: null,
@@ -196,10 +194,6 @@ export const getters = {
196194
return state.pooling
197195
},
198196

199-
getCanPoll(state: State): boolean {
200-
return state.canPoll
201-
},
202-
203197
getIsArchived(state: State): boolean {
204198
return state.archivedThreads
205199
},
@@ -273,10 +267,6 @@ export const mutations = {
273267
state.loadingThreads = payload
274268
},
275269

276-
setCanPoll(state: State, payload: boolean) {
277-
state.canPoll = payload
278-
},
279-
280270
resetState(state: State) {
281271
state.threads = []
282272
state.billingUsage = null
@@ -285,7 +275,6 @@ export const mutations = {
285275
state.user = null
286276
state.threadId = null
287277
state.archivedThreads = false
288-
state.canPoll = false
289278
state.pooling = false
290279
state.owner = null
291280
setApiKey('')
@@ -339,10 +328,6 @@ export const actions = {
339328
context.commit('setArchivedThreads', !context.getters.getIsArchived)
340329
},
341330

342-
setCanPoll(context: ActionContext<State, State>, payload: boolean) {
343-
context.commit('setCanPoll', payload)
344-
},
345-
346331
async loadPhones(context: ActionContext<State, State>, force: boolean) {
347332
if (context.getters.getPhones.length > 0 && !force) {
348333
return

0 commit comments

Comments
 (0)