diff --git a/packages/backend-rs/index.d.ts b/packages/backend-rs/index.d.ts index dec480d79c..001ee6f679 100644 --- a/packages/backend-rs/index.d.ts +++ b/packages/backend-rs/index.d.ts @@ -1120,6 +1120,13 @@ export interface Webhook { latestSentAt: Date | null latestStatus: number | null } +export enum ChatEvent { + Message = 'message', + Read = 'read', + Deleted = 'deleted', + Typing = 'typing' +} +export function publishToChatStream(senderUserId: string, receiverUserId: string, kind: ChatEvent, object: any): void /** Initializes Cuid2 generator. Must be called before any [create_id]. */ export function initIdGenerator(length: number, fingerprint: string): void export function getTimestamp(id: string): number diff --git a/packages/backend-rs/index.js b/packages/backend-rs/index.js index d801e28fce..411a39e050 100644 --- a/packages/backend-rs/index.js +++ b/packages/backend-rs/index.js @@ -310,7 +310,7 @@ if (!nativeBinding) { throw new Error(`Failed to load native binding`) } -const { loadEnv, loadConfig, stringToAcct, acctToString, addNoteToAntenna, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding +const { loadEnv, loadConfig, stringToAcct, acctToString, addNoteToAntenna, isBlockedServer, isSilencedServer, isAllowedServer, checkWordMute, getFullApAccount, isSelfHost, isSameOrigin, extractHost, toPuny, isUnicodeEmoji, sqlLikeEscape, safeForSql, formatMilliseconds, getNoteSummary, toMastodonId, fromMastodonId, fetchMeta, metaToPugArgs, nyaify, hashPassword, verifyPassword, isOldPasswordAlgorithm, decodeReaction, countReactions, toDbReaction, AntennaSrcEnum, DriveFileUsageHintEnum, MutedNoteReasonEnum, NoteVisibilityEnum, NotificationTypeEnum, PageVisibilityEnum, PollNotevisibilityEnum, RelayStatusEnum, UserEmojimodpermEnum, UserProfileFfvisibilityEnum, UserProfileMutingnotificationtypesEnum, ChatEvent, publishToChatStream, initIdGenerator, getTimestamp, genId, secureRndstr } = nativeBinding module.exports.loadEnv = loadEnv module.exports.loadConfig = loadConfig @@ -353,6 +353,8 @@ module.exports.RelayStatusEnum = RelayStatusEnum module.exports.UserEmojimodpermEnum = UserEmojimodpermEnum module.exports.UserProfileFfvisibilityEnum = UserProfileFfvisibilityEnum module.exports.UserProfileMutingnotificationtypesEnum = UserProfileMutingnotificationtypesEnum +module.exports.ChatEvent = ChatEvent +module.exports.publishToChatStream = publishToChatStream module.exports.initIdGenerator = initIdGenerator module.exports.getTimestamp = getTimestamp module.exports.genId = genId diff --git a/packages/backend-rs/src/service/stream.rs b/packages/backend-rs/src/service/stream.rs index 1e84d5f866..46fafa64ba 100644 --- a/packages/backend-rs/src/service/stream.rs +++ b/packages/backend-rs/src/service/stream.rs @@ -1,4 +1,5 @@ pub mod antenna; +pub mod chat; use crate::config::CONFIG; use crate::database::redis_conn; @@ -51,7 +52,7 @@ pub enum Error { pub fn publish_to_stream( stream: &Stream, - kind: Option<&str>, + kind: Option, value: Option, ) -> Result<(), Error> { let message = if let Some(kind) = kind { diff --git a/packages/backend-rs/src/service/stream/antenna.rs b/packages/backend-rs/src/service/stream/antenna.rs index 08ae391caf..3a829df546 100644 --- a/packages/backend-rs/src/service/stream/antenna.rs +++ b/packages/backend-rs/src/service/stream/antenna.rs @@ -4,7 +4,7 @@ use crate::service::stream::{publish_to_stream, Error, Stream}; pub fn publish(antenna_id: String, note: ¬e::Model) -> Result<(), Error> { publish_to_stream( &Stream::Antenna { antenna_id }, - Some("note"), + Some("note".to_string()), Some(serde_json::to_string(note)?), ) } diff --git a/packages/backend-rs/src/service/stream/chat.rs b/packages/backend-rs/src/service/stream/chat.rs new file mode 100644 index 0000000000..ae2efce938 --- /dev/null +++ b/packages/backend-rs/src/service/stream/chat.rs @@ -0,0 +1,31 @@ +use crate::service::stream::{publish_to_stream, Error, Stream}; + +#[derive(strum::Display)] +#[crate::export(string_enum = "camelCase")] +pub enum ChatEvent { + #[strum(serialize = "message")] + Message, + #[strum(serialize = "read")] + Read, + #[strum(serialize = "deleted")] + Deleted, + #[strum(serialize = "typing")] + Typing, +} + +#[crate::export(js_name = "publishToChatStream")] +pub fn publish( + sender_user_id: String, + receiver_user_id: String, + kind: ChatEvent, + object: &serde_json::Value, // TODO?: change this to enum +) -> Result<(), Error> { + publish_to_stream( + &Stream::Chat { + sender_user_id, + receiver_user_id, + }, + Some(kind.to_string()), + Some(serde_json::to_string(object)?), + ) +} diff --git a/packages/backend/src/server/api/common/read-messaging-message.ts b/packages/backend/src/server/api/common/read-messaging-message.ts index fc22c843af..20777c8246 100644 --- a/packages/backend/src/server/api/common/read-messaging-message.ts +++ b/packages/backend/src/server/api/common/read-messaging-message.ts @@ -2,7 +2,7 @@ import { publishMainStream, publishGroupMessagingStream, } from "@/services/stream.js"; -import { publishMessagingStream } from "@/services/stream.js"; +import { publishToChatStream, ChatEvent } from "backend-rs"; import { publishMessagingIndexStream } from "@/services/stream.js"; import { pushNotification } from "@/services/push-notification.js"; import type { User, IRemoteUser } from "@/models/entities/user.js"; @@ -54,7 +54,7 @@ export async function readUserMessagingMessage( ); // Publish event - publishMessagingStream(otherpartyId, userId, "read", messageIds); + publishToChatStream(otherpartyId, userId, ChatEvent.Read, messageIds); publishMessagingIndexStream(userId, "read", messageIds); if (!(await Users.getHasUnreadMessagingMessage(userId))) { diff --git a/packages/backend/src/server/api/stream/index.ts b/packages/backend/src/server/api/stream/index.ts index 313719e207..97337bd7e1 100644 --- a/packages/backend/src/server/api/stream/index.ts +++ b/packages/backend/src/server/api/stream/index.ts @@ -4,7 +4,6 @@ import readNote from "@/services/note/read.js"; import type { User } from "@/models/entities/user.js"; import type { Channel as ChannelModel } from "@/models/entities/channel.js"; import { - Users, Followings, Mutings, RenoteMutings, @@ -18,8 +17,8 @@ import type { UserProfile } from "@/models/entities/user-profile.js"; import { publishChannelStream, publishGroupMessagingStream, - publishMessagingStream, } from "@/services/stream.js"; +import { publishToChatStream, ChatEvent } from "backend-rs"; import type { UserGroup } from "@/models/entities/user-group.js"; import type { Packed } from "@/misc/schema.js"; import { readNotification } from "@/server/api/common/read-notification.js"; @@ -525,10 +524,10 @@ export default class Connection { }) { if (this.user) { if (param.partner) { - publishMessagingStream( + publishToChatStream( param.partner, this.user.id, - "typing", + ChatEvent.Typing, this.user.id, ); } else if (param.group) { diff --git a/packages/backend/src/services/messages/create.ts b/packages/backend/src/services/messages/create.ts index 257a132e6b..562e92e42a 100644 --- a/packages/backend/src/services/messages/create.ts +++ b/packages/backend/src/services/messages/create.ts @@ -7,10 +7,9 @@ import { Mutings, Users, } from "@/models/index.js"; -import { genId, toPuny } from "backend-rs"; +import { genId, publishToChatStream, toPuny, ChatEvent } from "backend-rs"; import type { MessagingMessage } from "@/models/entities/messaging-message.js"; import { - publishMessagingStream, publishMessagingIndexStream, publishMainStream, publishGroupMessagingStream, @@ -52,10 +51,10 @@ export async function createMessage( if (recipientUser) { if (Users.isLocalUser(user)) { // 自分のストリーム - publishMessagingStream( + publishToChatStream( message.userId, recipientUser.id, - "message", + ChatEvent.Message, messageObj, ); publishMessagingIndexStream(message.userId, "message", messageObj); @@ -64,10 +63,10 @@ export async function createMessage( if (Users.isLocalUser(recipientUser)) { // 相手のストリーム - publishMessagingStream( + publishToChatStream( recipientUser.id, message.userId, - "message", + ChatEvent.Message, messageObj, ); publishMessagingIndexStream(recipientUser.id, "message", messageObj); diff --git a/packages/backend/src/services/messages/delete.ts b/packages/backend/src/services/messages/delete.ts index 2d8f6b9baf..745c89380d 100644 --- a/packages/backend/src/services/messages/delete.ts +++ b/packages/backend/src/services/messages/delete.ts @@ -1,10 +1,8 @@ import { config } from "@/config.js"; import { MessagingMessages, Users } from "@/models/index.js"; import type { MessagingMessage } from "@/models/entities/messaging-message.js"; -import { - publishGroupMessagingStream, - publishMessagingStream, -} from "@/services/stream.js"; +import { publishGroupMessagingStream } from "@/services/stream.js"; +import { publishToChatStream, ChatEvent } from "backend-rs"; import { renderActivity } from "@/remote/activitypub/renderer/index.js"; import renderDelete from "@/remote/activitypub/renderer/delete.js"; import renderTombstone from "@/remote/activitypub/renderer/tombstone.js"; @@ -21,17 +19,17 @@ async function postDeleteMessage(message: MessagingMessage) { const recipient = await Users.findOneByOrFail({ id: message.recipientId }); if (Users.isLocalUser(user)) - publishMessagingStream( + publishToChatStream( message.userId, message.recipientId, - "deleted", + ChatEvent.Deleted, message.id, ); if (Users.isLocalUser(recipient)) - publishMessagingStream( + publishToChatStream( message.recipientId, message.userId, - "deleted", + ChatEvent.Deleted, message.id, ); diff --git a/packages/backend/src/services/stream.ts b/packages/backend/src/services/stream.ts index 7f1862b74d..00d33dbb30 100644 --- a/packages/backend/src/services/stream.ts +++ b/packages/backend/src/services/stream.ts @@ -17,7 +17,7 @@ import type { InternalStreamTypes, MainStreamTypes, MessagingIndexStreamTypes, - MessagingStreamTypes, + // MessagingStreamTypes, NoteStreamTypes, UserListStreamTypes, UserStreamTypes, @@ -147,18 +147,19 @@ class Publisher { // ); // }; - public publishMessagingStream = ( - userId: User["id"], - otherpartyId: User["id"], - type: K, - value?: MessagingStreamTypes[K], - ): void => { - this.publish( - `messagingStream:${userId}-${otherpartyId}`, - type, - typeof value === "undefined" ? null : value, - ); - }; + /* ported to backend-rs */ + // public publishMessagingStream = ( + // userId: User["id"], + // otherpartyId: User["id"], + // type: K, + // value?: MessagingStreamTypes[K], + // ): void => { + // this.publish( + // `messagingStream:${userId}-${otherpartyId}`, + // type, + // typeof value === "undefined" ? null : value, + // ); + // }; public publishGroupMessagingStream = < K extends keyof GroupMessagingStreamTypes, @@ -219,7 +220,7 @@ export const publishNotesStream = publisher.publishNotesStream; export const publishChannelStream = publisher.publishChannelStream; export const publishUserListStream = publisher.publishUserListStream; // export const publishAntennaStream = publisher.publishAntennaStream; -export const publishMessagingStream = publisher.publishMessagingStream; +// export const publishMessagingStream = publisher.publishMessagingStream; export const publishGroupMessagingStream = publisher.publishGroupMessagingStream; export const publishMessagingIndexStream =