feat: add WhatsApp group sync to database

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 15:19:15 +05:30
parent 81da0d483e
commit 0d45bd8bd6
2 changed files with 124 additions and 0 deletions
@@ -0,0 +1,99 @@
import { syncGroups } from './group-sync';
import { GroupMetadata } from '@whiskeysockets/baileys';
const mockGroups: Record<string, GroupMetadata> = {
'120363043312345678@g.us': {
id: '120363043312345678@g.us',
subject: 'UP Parivar Dallas',
desc: 'Main community group',
participants: [],
creation: 0,
owner: undefined,
restrict: false,
announce: false,
subjectOwner: undefined,
subjectTime: 0,
size: 0,
ephemeralDuration: 0,
inviteCode: undefined,
},
'999999999@g.us': {
id: '999999999@g.us',
subject: 'Events Committee',
desc: undefined,
participants: [],
creation: 0,
owner: undefined,
restrict: false,
announce: false,
subjectOwner: undefined,
subjectTime: 0,
size: 0,
ephemeralDuration: 0,
inviteCode: undefined,
},
};
const mockPrisma = {
group: {
upsert: jest.fn(),
},
};
describe('syncGroups', () => {
beforeEach(() => jest.clearAllMocks());
it('upserts each group and returns jid→id map', async () => {
mockPrisma.group.upsert
.mockResolvedValueOnce({ id: 'db-group-1' })
.mockResolvedValueOnce({ id: 'db-group-2' });
const result = await syncGroups(mockGroups, mockPrisma as any);
expect(mockPrisma.group.upsert).toHaveBeenCalledTimes(2);
expect(result.get('120363043312345678@g.us')).toBe('db-group-1');
expect(result.get('999999999@g.us')).toBe('db-group-2');
});
it('calls upsert with correct create payload', async () => {
mockPrisma.group.upsert.mockResolvedValue({ id: 'db-group-1' });
await syncGroups(
{ '120363043312345678@g.us': mockGroups['120363043312345678@g.us'] },
mockPrisma as any,
);
expect(mockPrisma.group.upsert).toHaveBeenCalledWith({
where: { platform_platformId: { platform: 'whatsapp', platformId: '120363043312345678@g.us' } },
create: {
platform: 'whatsapp',
platformId: '120363043312345678@g.us',
name: 'UP Parivar Dallas',
description: 'Main community group',
isActive: true,
},
update: { name: 'UP Parivar Dallas', description: 'Main community group' },
});
});
it('handles groups with no description', async () => {
mockPrisma.group.upsert.mockResolvedValue({ id: 'db-group-2' });
await syncGroups(
{ '999999999@g.us': mockGroups['999999999@g.us'] },
mockPrisma as any,
);
expect(mockPrisma.group.upsert).toHaveBeenCalledWith(
expect.objectContaining({
create: expect.objectContaining({ description: undefined }),
}),
);
});
it('returns an empty map when given empty groups', async () => {
const result = await syncGroups({}, mockPrisma as any);
expect(result.size).toBe(0);
expect(mockPrisma.group.upsert).not.toHaveBeenCalled();
});
});
+25
View File
@@ -0,0 +1,25 @@
import { GroupMetadata } from '@whiskeysockets/baileys';
export async function syncGroups(
groups: Record<string, GroupMetadata>,
prisma: any,
): Promise<Map<string, string>> {
const jidToDbId = new Map<string, string>();
for (const [jid, meta] of Object.entries(groups)) {
const group = await prisma.group.upsert({
where: { platform_platformId: { platform: 'whatsapp', platformId: jid } },
create: {
platform: 'whatsapp',
platformId: jid,
name: meta.subject,
description: meta.desc ?? undefined,
isActive: true,
},
update: { name: meta.subject, description: meta.desc ?? undefined },
});
jidToDbId.set(jid, group.id);
}
return jidToDbId;
}