Skip to content

Commit

Permalink
Merge pull request #115 from traP-jp/improve-notify-messeges
Browse files Browse the repository at this point in the history
1つのメッセージに複数の登録単語が含まれていた時に、1つのDMでまとめて通知するようにした
  • Loading branch information
oribe1115 authored Oct 25, 2023
2 parents 26fdc4f + efde602 commit e726455
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 10 deletions.
58 changes: 58 additions & 0 deletions server/model/traqMessage.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package model

import (
"fmt"
"strings"

"golang.org/x/exp/slog"
Expand Down Expand Up @@ -80,6 +81,47 @@ func TraqMessageProcessor(messageList MessageList) (SendList, error) {
return sendList, nil
}

func FindMatchingWords(messageList MessageList) ([]*NotifyInfo, error) {
notifyInfoList := make([]*NotifyInfo, 0)

// メッセージごとに通知対象を検索する
for _, messageItem := range messageList {
// メッセージに含まれている登録単語で、通知条件が合致するものを登録者別にまとめる
matchedWordsList := make([]*MatchedWords, 0)
err := db.Select(&matchedWordsList, `
SELECT
group_concat(words.word SEPARATOR ':::') AS contacted_words,
words.trap_id AS trap_id,
users.traq_uuid AS traq_uuid
FROM words
JOIN users ON words.trap_id = users.trap_id
WHERE ? LIKE concat('%', word, '%')
AND (me_notification OR
users.traq_uuid != ?)
AND (bot_notification OR
(SELECT is_bot FROM users WHERE traq_uuid = ? LIMIT 1) = FALSE)
GROUP BY words.trap_id`,
messageItem.Content, messageItem.TraqUuid, messageItem.TraqUuid)
if err != nil {
slog.Error(fmt.Sprintf("failed to search words with message: `%s`", messageItem.Id))
return nil, err
}

for _, matchedWords := range matchedWordsList {
notifyInfo := &NotifyInfo{
Words: strings.Split(matchedWords.ContactedWords, ":::"),
NotifyTargetTrapId: matchedWords.TrapID,
NotifyTargetTraqUuid: matchedWords.TraqUUID,
MessageId: messageItem.Id,
}

notifyInfoList = append(notifyInfoList, notifyInfo)
}
}

return notifyInfoList, nil
}

type MessageItem struct {
// メッセージUUID
Id string `json:"id"`
Expand Down Expand Up @@ -118,3 +160,19 @@ type Send struct {
}

type SendList []*Send

type NotifyInfo struct {
Words []string
// 送信先のuser
NotifyTargetTrapId string
// 送信先のuserUUID
NotifyTargetTraqUuid string
// 送信するメッセージのID
MessageId string
}

type MatchedWords struct {
ContactedWords string `db:"contacted_words"`
TrapID string `db:"trap_id"`
TraqUUID string `db:"traq_uuid"`
}
28 changes: 18 additions & 10 deletions server/traqmessage/collect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"h23s_15/model"
"strings"
"time"

"github.com/traPtitech/go-traq"
Expand Down Expand Up @@ -39,16 +40,16 @@ func messageProcessor(messages []traq.Message) {
slog.Error(fmt.Sprintf("Failled to convert messages: %v", err))
return
}
sendList, err := model.TraqMessageProcessor(messageList)
notifyInfoList, err := model.FindMatchingWords(messageList)
if err != nil {
slog.Error(fmt.Sprintf("Failled to process messages: %v", err))
return
}

slog.Info(fmt.Sprintf("Sending %d DMs...", len(sendList)))
slog.Info(fmt.Sprintf("Sending %d DMs...", len(notifyInfoList)))

for _, message := range sendList {
err := sendMessage(*message)
for _, notifyInfo := range notifyInfoList {
err := sendMessage(notifyInfo.NotifyTargetTraqUuid, genNotifyMessageContent(notifyInfo.MessageId, notifyInfo.Words...))
if err != nil {
slog.Error(fmt.Sprintf("Failled to send message: %v", err))
continue
Expand All @@ -58,19 +59,26 @@ func messageProcessor(messages []traq.Message) {
slog.Info("End of send DMs")
}

func sendMessage(message model.Send) error {
// TODO: 送信処理
// 送信先User: message.UserUUID
// 送信内容: "ワード:"+message.Word+"\n https://q.trap.jp/messages/"+message.MessageId
func genNotifyMessageContent(citeMessageId string, words ...string) string {
list := make([]string, 0)
for _, word := range words {
item := fmt.Sprintf("「%s」", word)
list = append(list, item)
}

return fmt.Sprintf("%s\n https://q.trap.jp/messages/%s", strings.Join(list, ""), citeMessageId)
}

func sendMessage(notifyTargetTraqUUID string, messageContent string) error {
if model.ACCESS_TOKEN == "" {
slog.Info("Skip sendMessage")
return nil
}

client := traq.NewAPIClient(traq.NewConfiguration())
auth := context.WithValue(context.Background(), traq.ContextAccessToken, model.ACCESS_TOKEN)
_, _, err := client.UserApi.PostDirectMessage(auth, message.NotifyTargetTraqUuid).PostMessageRequest(traq.PostMessageRequest{
Content: "「 " + message.Word + " 」\n https://q.trap.jp/messages/" + message.MessageId,
_, _, err := client.UserApi.PostDirectMessage(auth, notifyTargetTraqUUID).PostMessageRequest(traq.PostMessageRequest{
Content: messageContent,
}).Execute()
if err != nil {
slog.Info("Error sending message: %v", err)
Expand Down

0 comments on commit e726455

Please sign in to comment.