Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Commit

Permalink
fix #14 ユーザー名もしくはメンションが正しく置換されない問題を修正
Browse files Browse the repository at this point in the history
  • Loading branch information
yogarasu committed Aug 19, 2022
1 parent 28e386d commit cd288bf
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 129 deletions.
40 changes: 38 additions & 2 deletions command/build/message.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Spinner } from "../../libs/util/spinner.mjs"
import { getChannelFile } from "../../libs/channel.mjs"
import { buildAllMessageFile } from "../../libs/message.mjs"
import { getUserFile } from "../../libs/user.mjs"
import { createSlackClient } from "../../libs/client.mjs"

const __dirname = new URL(import.meta.url).pathname
const distDirPath = resolve(__dirname, "../../../.dist/")
Expand All @@ -14,9 +15,40 @@ const distUserFilePath = join(distDirPath, "user.json")
dotenv.config({ path: "./.envrc" })
const spinner = new Spinner()

interface Options {
slackBotToken?: string
}

;(async () => {
const program = new Command()
program.description("Build message file command").parse(process.argv)
program
.description("Build message file command")
.requiredOption(
"-st, --slack-bot-token [string]",
"SlackBot OAuth Token",
process.env.SLACK_BOT_TOKEN
)
.parse(process.argv)

// パラメーターの取得
spinner.loading("Check parameter")
const options: Options = program.opts()
const { slackBotToken } = options
if (slackBotToken === undefined) {
spinner.failed(null, "Required parameter is not found")
process.exit(0)
}
spinner.success()

// Slackのクライアントを作成する
spinner.loading("Create slack client")
const { slackClient, ...createSlackClientResult } =
createSlackClient(slackBotToken)
if (!slackClient || createSlackClientResult.status === "failed") {
spinner.failed(null, createSlackClientResult.message)
process.exit(0)
}
spinner.success()

// チャンネルを取得する
spinner.loading("Get channel")
Expand All @@ -40,7 +72,11 @@ const spinner = new Spinner()

// メッセージファイルを作成する
spinner.loading("Build message file")
const buildAllMessageFileResult = await buildAllMessageFile(channels, users)
const buildAllMessageFileResult = await buildAllMessageFile(
slackClient,
channels,
users
)
if (buildAllMessageFileResult.status === "failed") {
spinner.failed(null, buildAllMessageFileResult.message)
process.exit(0)
Expand Down
21 changes: 1 addition & 20 deletions command/build/user.mts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { resolve, join } from "node:path"
import { Spinner } from "../../libs/util/spinner.mjs"
import { buildUser } from "../../libs/user.mjs"
import { getChannelFile } from "../../libs/channel.mjs"
import { getMessageBotId, getBotData } from "../../libs/bot.mjs"
import { createSlackClient } from "../../libs/client.mjs"

const __dirname = new URL(import.meta.url).pathname
Expand Down Expand Up @@ -63,28 +62,10 @@ interface Options {
}
spinner.success()

// メッセージファイル内のBotIdを取得する
spinner.loading("Get BotId in message file")
const { botIds, ...getMessageBotIdResult } = await getMessageBotId(channels)
if (getMessageBotIdResult.status === "failed") {
spinner.failed(null, getMessageBotIdResult.message)
process.exit(0)
}
spinner.success

// Botのデータを取得する
spinner.loading("Get bot data")
const { bots, ...getBotDataResult } = await getBotData(slackClient, botIds)
if (getBotDataResult.status === "failed") {
spinner.failed(null, getBotDataResult.message)
process.exit(0)
}
spinner.success

// ユーザーファイルを作成する
spinner.loading("Build user file")
try {
await buildUser(srcUserFilePath, distUserFilePath, bots)
await buildUser(srcUserFilePath, distUserFilePath)
} catch (error) {
spinner.failed(null, error)
process.exit(0)
Expand Down
75 changes: 0 additions & 75 deletions libs/bot.mts

This file was deleted.

50 changes: 41 additions & 9 deletions libs/message.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from "@slack/web-api/dist/response/ChatPostMessageResponse"
import { ChannelType, EmbedType } from "discord.js"
import type { Guild as DiscordClientType, APIEmbed as Embed } from "discord.js"
import type { WebClient as SlackClientType } from "@slack/web-api"
import { getUser, getUsername } from "./user.mjs"
import type { User } from "./user.mjs"
import type { Channel } from "./channel.mjs"

Expand Down Expand Up @@ -93,6 +95,7 @@ export const createMessageFile = async (
* @param users
*/
export const buildMessageFile = async (
slackClient: SlackClientType,
srcMessageFilePath: string,
distMessageFilePath: string,
users: User[],
Expand All @@ -113,17 +116,35 @@ export const buildMessageFile = async (
let content = message.text || ""

// メッセージ内のユーザー名もしくはBot名のメンションを、Discordでメンションされない形式に置換
if (/<@U[A-Z0-9]{10}>/.test(content)) {
for (const user of users) {
if (new RegExp(`<@${user.slack.id}>`, "g").test(content)) {
content = content.replaceAll(
new RegExp(`<@${user.slack.id}>`, "g"),
`@${user.discord.name}`
)
const matchMention = content.match(/<@U[A-Z0-9]{10}>/g)
if (matchMention?.length) {
const userIds = matchMention.map((mention) =>
mention.replace(/<@|>/g, "")
)
for (const userId of userIds) {
const user = users.find((user) => user.slack.id === userId)
if (user && user.slack.name) {
content = content.replaceAll(`<@${userId}>`, `@${user.slack.name}`)
} else {
// usersにないメンションは、APIから取得する
const getUsernameResult = await getUsername(slackClient, userId)
const username = getUsernameResult.username
if (username && getUsernameResult.status === "success") {
content = content.replaceAll(`<@${userId}>`, `@${username}`)
} else {
throw new Error(
`Failed to convert mention of @${userId} to username\n` +
getUsernameResult.message
)
}
}
}
}

// メッセージ内のチャンネルメンションタグを、Discordで表示される形式に置換
if (/<!channel>/.test(content))
content = content.replaceAll(/<!channel>/g, "@channel")

// メッセージ内の太文字を、Discordで表示される形式に置換
if (/\*.*\*/.test(content)) content = content.replaceAll(/\**\*/g, "**")

Expand All @@ -149,13 +170,22 @@ export const buildMessageFile = async (
]

// メッセージの送信者情報を取得
const user = users.find(
let user = users.find(
(user) =>
user.slack.id === message.user ||
user.slack.bot?.app_id === message.app_id
)
// メッセージの送信者情報が取得できない場合は、APIから取得
if (!user) {
throw new Error("Failed to get user for message")
if (message.user) {
const getUserResult = await getUser(slackClient, message.user)
if (getUserResult.user) {
user = getUserResult.user
}
}
if (!user) {
throw new Error("Failed to get user for message")
}
}
const anthor: Message["slack"]["anthor"] = {
id: user.slack.id,
Expand Down Expand Up @@ -246,6 +276,7 @@ export const buildMessageFile = async (
* @param users
*/
export const buildAllMessageFile = async (
slackClient: SlackClientType,
channels: Channel[],
users: User[]
): Promise<{
Expand All @@ -264,6 +295,7 @@ export const buildAllMessageFile = async (
const distMessageFilePath =
channel.discord.message_file_paths[index]
const buildMessageFileResult = await buildMessageFile(
slackClient,
srcMessageFilePath,
distMessageFilePath,
users,
Expand Down
Loading

0 comments on commit cd288bf

Please sign in to comment.