When I do the following:
const queryChannelsResponse = await this.client.queryChannels(
{ id: channelId },
{ last_updated_at: -1 },
{ state: true },
This does not include the members. How am I able to get the member information?
I am writing a webhook and I want it to send a push notification (I am currently sending these myself via expo) to all offline users.
I am migrating from pusher chatkit which is now being discontinued. They had a new_message_users_offline hook for this purpose.
In the message.new webhook payload in the documentation the members are present but they are not present in the request body:
{
"type": "message.new",
"cid": "messaging:394f36fd-d512-4f2b-a785-ab8dfe82af49",
"message": {
"id": "f73ee1a8-f6fd-450b-bc64-0840b4df8fd9-2b4908ad-e267-4c48-8f41-8c26c8f769ce",
"text": "Ffddf",
"html": "<p>Ffddf</p>\n",
"type": "regular",
"user": {
"id": "f73ee1a8-f6fd-450b-bc64-0840b4df8fd9",
"role": "user",
"created_at": "2020-04-06T14:06:37.979584Z",
"updated_at": "2020-04-06T19:45:39.556842Z",
"last_active": "2020-04-06T19:45:39.54939Z",
"banned": false,
"online": true,
"name": "Mark Everett",
"image": "https://8dc-user-files-dev.s3.eu-west-1.amazonaws.com/MEMBER_PROFILE_IMAGE-f73ee1a8-f6fd-450b-bc64-0840b4df8fd9.png?v=6"
},
"attachments": [],
"latest_reactions": [],
"own_reactions": [],
"reaction_counts": null,
"reaction_scores": {},
"reply_count": 0,
"created_at": "2020-04-06T19:51:14.114803Z",
"updated_at": "2020-04-06T19:51:14.114803Z",
"mentioned_users": []
},
"user": {
"id": "f73ee1a8-f6fd-450b-bc64-0840b4df8fd9",
"role": "user",
"created_at": "2020-04-06T14:06:37.979584Z",
"updated_at": "2020-04-06T19:45:39.556842Z",
"last_active": "2020-04-06T19:45:39.54939Z",
"banned": false,
"online": true,
"channel_unread_count": 0,
"channel_last_read_at": "1970-01-01T00:00:00Z",
"total_unread_count": 0,
"unread_channels": 0,
"unread_count": 0,
"image": "https://8dc-user-files-dev.s3.eu-west-1.amazonaws.com/MEMBER_PROFILE_IMAGE-f73ee1a8-f6fd-450b-bc64-0840b4df8fd9.png?v=6",
"name": "Mark Everett"
},
"watcher_count": 1,
"created_at": "2020-04-06T19:51:14.121213459Z",
"channel_type": "messaging",
"channel_id": "394f36fd-d512-4f2b-a785-ab8dfe82af49"
}
My plan is do do something like this:
public async getOfflineUserIds(channelId: string): Promise<string[]> {
try {
// Get the channel
const queryChannelsResponse = await this.client.queryChannels(
{ id: channelId },
{ last_updated_at: -1 },
{ message_limit: 0, limit: 1, state: true},
)
const channel = queryChannelsResponse[0]
console.log('channel: ', channel)
// Get the channels members
const userIds: string[] = []
// tslint:disable-next-line: forin
for (const index in channel.state.members) {
userIds.push(channel.state.members[index].user_id)
}
console.log('userIds:', userIds)
const queryUsersResponse = await this.client.queryUsers(
{ id: { $in: userIds } },
{ last_active: -1 },
{},
)
console.log('queryUsersResponse:', queryUsersResponse)
// Work out who is offline/online
const offlineUserIds = queryUsersResponse.users
.filter(u => !u.online)
.map(u => u.id)
return offlineUserIds
} catch (err) {
throw new InternalServerErrorException(
'Error getting offline users for channel.',
err,
)
}
}
This is now resolved.
I did not add the members to the channel with channel.addMembers
. I create and add members on the server as this works perfectly for my use case.
If it helps anyone I ended up with these two methods:
public async getChannelUserIds(channelId: string): Promise<string[]> {
try {
const queryChannelsResponse = await this.client.queryChannels(
{ id: channelId },
{ last_updated_at: -1 },
{ message_limit: 0, limit: 1, state: true },
)
const channel = queryChannelsResponse[0]
const userIds = Object.keys(channel.state.members)
console.log('userIds:', userIds)
return userIds
} catch (err) {
throw new InternalServerErrorException(
`Error getting user ids for channel ('${channelId}').`,
err,
)
}
}
public async getOfflineUserIds(userIds: string[]): Promise<string[]> {
try {
const queryUsersResponse = await this.client.queryUsers(
{ id: { $in: userIds } },
{ last_active: -1 },
{},
)
console.log('queryUsersResponse:', queryUsersResponse)
const offlineUserIds = queryUsersResponse.users
.filter(u => !u.online)
.map(u => u.user_id)
return offlineUserIds
} catch (err) {
throw new InternalServerErrorException(
`Error getting offline user ids from ('${JSON.stringify(
userIds,
null,
2,
)}').`,
err,
)
}
}
And then in my webhook I:
@Post('stream/messages')
public async onReceive(
@Req() req: Request,
@Headers('x-signature') signature: string,
@Body() body: any,
) {
try {
console.debug('webhooks-stream.messages.onReceive')
this.chatService.verifyWebhook((req as any).rawBody, signature)
console.log('DEBUG WEBHOOK BODY', JSON.stringify(body, null, 2))
switch (body.type) {
case 'message.new': {
const offlineMemberIds = await this.chatService.getOfflineUserIds(
body.members.map(member => member.user_id),
)
...