Skip to content

Commit

Permalink
Upsert user list to database
Browse files Browse the repository at this point in the history
  • Loading branch information
joonashak committed Aug 1, 2023
1 parent ce2f568 commit f76d285
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
11 changes: 7 additions & 4 deletions app-nest/src/entities/user/user.entity.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Column, Entity, PrimaryGeneratedColumn, Repository } from "typeorm";
import { Column, Entity, PrimaryColumn, Repository } from "typeorm";

@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@PrimaryColumn()
slackId: string;

@Column()
slackId: string;
displayName: string;

@Column()
realName: string;
}

export type UserRepository = Repository<User>;
16 changes: 15 additions & 1 deletion app-nest/src/entities/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
import { Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { DataSource } from "typeorm";
import { User, UserRepository } from "./user.entity";

@Injectable()
export class UserService {
constructor(@InjectRepository(User) private userRepository: UserRepository) {}
constructor(
@InjectRepository(User) private userRepository: UserRepository,
private dataSource: DataSource,
) {}

async findAll() {
return this.userRepository.find();
}

async upsert(users: User[]) {
return this.dataSource
.createQueryBuilder()
.insert()
.into(User)
.values(users)
.orUpdate(["displayName", "realName"], ["slackId"])
.execute();
}
}
7 changes: 6 additions & 1 deletion app-nest/src/sync/sync.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Module } from "@nestjs/common";
import { UserModule } from "../entities/user/user.module";
import { UserService } from "../entities/user/user.service";
import { SyncService } from "./sync.service";
import { UserSyncService } from "./user-sync.service";

@Module({ providers: [SyncService, UserSyncService] })
@Module({
imports: [UserModule],
providers: [SyncService, UserSyncService, UserService],
})
export class SyncModule {}
41 changes: 33 additions & 8 deletions app-nest/src/sync/user-sync.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,42 @@
import { Injectable } from "@nestjs/common";
import { Injectable, Logger } from "@nestjs/common";
import { UsersListResponse } from "@slack/web-api";
import { BoltUserService } from "../bolt/bolt-user.service";
import { UserService } from "../entities/user/user.service";

@Injectable()
export class UserSyncService {
constructor(private boltUserService: BoltUserService) {}
private logger = new Logger(UserSyncService.name);

constructor(
private boltUserService: BoltUserService,
private userService: UserService,
) {}

async syncUsers() {
const users = await this.boltUserService.getUsers();
// FIXME: This needs to be limited in dev env to protect against rate-limit errors. Add UI button to fire this manually.
this.logger.log("Starting user data synchronization.");
const data = await this.boltUserService.getUsers();

const users = data.members.filter(this.appUserFilter).map((user) => ({
slackId: user.id,
displayName: user.profile.display_name || "",
realName: user.profile.real_name || "",
}));

await this.userService.upsert(users);
this.logger.log("User data synchronized.");
}

// console.log(users);
for (const user of users.members) {
console.log(user);
console.log(user.profile);
}
/**
* Filter out bots, restricted and deleted users, leaving only real app users.
*/
private appUserFilter(user: UsersListResponse["members"][0]) {
return (
user.id !== "USLACKBOT" &&
!user.is_bot &&
!user.is_restricted &&
!user.is_ultra_restricted &&
!user.deleted
);
}
}

0 comments on commit f76d285

Please sign in to comment.