Overriding the context finally worked for me, with the help of thisthis answer:
override = bpy.context.copy()
for area in bpy.context.screen.areas:
if area.type == 'OUTLINER':
override['area'] = area
bpy.ops.outliner.group_operation(override, type='LINK')