const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() const _ = db.command exports.main = async event => { const { OPENID } = cloud.getWXContext() const content = String(event.content || '').trim() if (!content) throw new Error('content is required') const now = Date.now() let convId = event.conversationId // Create a 1:1 conversation if not provided if (!convId) { let { toOpenid } = event // Allow opening by user id without exposing openids to the client. if (!toOpenid && event.toUserId) { const toUserById = await db.collection('users').doc(event.toUserId).get().catch(() => null) if (toUserById && toUserById.data) toOpenid = toUserById.data.openid } if (!toOpenid) throw new Error('conversationId or toOpenid/toUserId is required') // Look for existing conversation between these two users const existing = await db.collection('conversations') .where({ type: 'single', memberOpenids: _.all([OPENID, toOpenid]) }) .limit(1) .get() if (existing.data.length) { convId = existing.data[0]._id } else { const toUserRes = await db.collection('users').where({ openid: toOpenid }).limit(1).get() const toUser = toUserRes.data[0] || { nickname: '用户', avatarKey: 'gradient-avatar-1' } const newConv = await db.collection('conversations').add({ data: { type: 'single', memberOpenids: [OPENID, toOpenid], unreadOpenids: [toOpenid], unreadCounts: { [toOpenid]: 1 }, title: toUser.nickname, avatarKey: toUser.avatarKey, lastMessage: { content: content.slice(0, 50), createdAt: now }, pinned: false, muted: false, createdAt: now, updatedAt: now } }) convId = newConv._id } } // Add message to messages collection const msgResult = await db.collection('messages').add({ data: { conversationId: convId, fromOpenid: OPENID, content: content.slice(0, 1000), type: event.msgType || 'text', createdAt: now } }) // Update conversation: last message + unread counts for all recipients const convRes = await db.collection('conversations').doc(convId).get() const members = convRes.data.memberOpenids || [] const recipients = members.filter(id => id !== OPENID) const updateData = { lastMessage: { content: content.slice(0, 50), createdAt: now }, updatedAt: now } // Add recipients to unreadOpenids and increment their unread counts recipients.forEach(r => { updateData[`unreadCounts.${r}`] = _.inc(1) }) // Rebuild unreadOpenids to include all recipients (remove duplicates) const existingUnread = convRes.data.unreadOpenids || [] const newUnread = [...new Set([...existingUnread, ...recipients])] updateData.unreadOpenids = newUnread await db.collection('conversations').doc(convId).update({ data: updateData }) return { messageId: msgResult._id, conversationId: convId } }