You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
6.3 KiB
249 lines
6.3 KiB
import { models } from './models'
|
|
import * as md5 from 'md5'
|
|
import { keysendMessage } from './utils/lightning'
|
|
import {personalizeMessage} from './utils/msg'
|
|
|
|
const constants = require('../config/constants.json');
|
|
|
|
const findOrCreateChat = async (params) => {
|
|
const { chat_id, owner_id, recipient_id } = params
|
|
let chat
|
|
let date = new Date();
|
|
date.setMilliseconds(0)
|
|
|
|
if (chat_id) {
|
|
chat = await models.Chat.findOne({ where: { id: chat_id } })
|
|
// console.log('findOrCreateChat: chat_id exists')
|
|
} else {
|
|
console.log("chat does not exists, create new")
|
|
const owner = await models.Contact.findOne({ where: { id: owner_id } })
|
|
const recipient = await models.Contact.findOne({ where: { id: recipient_id } })
|
|
const uuid = md5([owner.publicKey, recipient.publicKey].sort().join("-"))
|
|
|
|
// find by uuid
|
|
chat = await models.Chat.findOne({ where:{uuid} })
|
|
|
|
if(!chat){ // no chat! create new
|
|
chat = await models.Chat.create({
|
|
uuid: uuid,
|
|
contactIds: JSON.stringify([parseInt(owner_id), parseInt(recipient_id)]),
|
|
createdAt: date,
|
|
updatedAt: date,
|
|
type: constants.chat_types.conversation
|
|
})
|
|
}
|
|
}
|
|
return chat
|
|
}
|
|
|
|
const sendContactKeys = async (args) => {
|
|
const { type, contactIds, contactPubKey, sender, success, failure } = args
|
|
const msg = newkeyexchangemsg(type, sender)
|
|
|
|
let yes:any = null
|
|
let no:any = null
|
|
let cids = contactIds
|
|
|
|
if(!contactIds) cids = [null] // nully
|
|
await asyncForEach(cids, async contactId => {
|
|
let destination_key:string
|
|
if(!contactId){ // nully
|
|
destination_key = contactPubKey
|
|
} else {
|
|
if (contactId == sender.id) {
|
|
return
|
|
}
|
|
const contact = await models.Contact.findOne({ where: { id: contactId } })
|
|
destination_key = contact.publicKey
|
|
}
|
|
performKeysendMessage({
|
|
destination_key,
|
|
amount: 3,
|
|
msg: JSON.stringify(msg),
|
|
success: (data) => {
|
|
yes = data
|
|
},
|
|
failure: (error) => {
|
|
no = error
|
|
}
|
|
})
|
|
})
|
|
if(no && failure){
|
|
failure(no)
|
|
}
|
|
if(!no && yes && success){
|
|
success(yes)
|
|
}
|
|
}
|
|
|
|
const sendMessage = async (params) => {
|
|
const { type, chat, message, sender, amount, success, failure } = params
|
|
const m = newmsg(type, chat, sender, message)
|
|
|
|
const contactIds = typeof chat.contactIds==='string' ? JSON.parse(chat.contactIds) : chat.contactIds
|
|
|
|
let yes:any = null
|
|
let no:any = null
|
|
console.log('all contactIds',contactIds)
|
|
await asyncForEach(contactIds, async contactId => {
|
|
if (contactId == sender.id) {
|
|
return
|
|
}
|
|
|
|
console.log('-> sending to contact #', contactId)
|
|
|
|
const contact = await models.Contact.findOne({ where: { id: contactId } })
|
|
const destkey = contact.publicKey
|
|
|
|
const finalMsg = await personalizeMessage(m, contactId, destkey)
|
|
|
|
const opts = {
|
|
dest: destkey,
|
|
data: JSON.stringify(finalMsg),
|
|
amt: amount || 3,
|
|
}
|
|
try {
|
|
const r = await keysendMessage(opts)
|
|
yes = r
|
|
} catch (e) {
|
|
console.log("KEYSEND ERROR", e)
|
|
no = e
|
|
}
|
|
})
|
|
if(yes){
|
|
if(success) success(yes)
|
|
} else {
|
|
if(failure) failure(no)
|
|
}
|
|
}
|
|
|
|
const performKeysendMessage = async ({ destination_key, amount, msg, success, failure }) => {
|
|
const opts = {
|
|
dest: destination_key,
|
|
data: msg || JSON.stringify({}),
|
|
amt: Math.max(amount, 3)
|
|
}
|
|
try {
|
|
const r = await keysendMessage(opts)
|
|
console.log("=> external keysend")
|
|
if (success) success(r)
|
|
} catch (e) {
|
|
console.log("MESSAGE ERROR", e)
|
|
if (failure) failure(e)
|
|
}
|
|
}
|
|
|
|
async function findOrCreateContactByPubkey(senderPubKey) {
|
|
let sender = await models.Contact.findOne({ where: { publicKey: senderPubKey } })
|
|
if (!sender) {
|
|
sender = await models.Contact.create({
|
|
publicKey: senderPubKey,
|
|
alias: "Unknown",
|
|
status: 1
|
|
})
|
|
|
|
const owner = await models.Contact.findOne({ where: { isOwner: true } })
|
|
sendContactKeys({
|
|
contactIds: [sender.id],
|
|
sender: owner,
|
|
type: constants.message_types.contact_key,
|
|
})
|
|
}
|
|
return sender
|
|
}
|
|
|
|
async function findOrCreateChatByUUID(chat_uuid, contactIds) {
|
|
let chat = await models.Chat.findOne({ where: { uuid: chat_uuid } })
|
|
if (!chat) {
|
|
var date = new Date();
|
|
date.setMilliseconds(0)
|
|
chat = await models.Chat.create({
|
|
uuid: chat_uuid,
|
|
contactIds: JSON.stringify(contactIds || []),
|
|
createdAt: date,
|
|
updatedAt: date,
|
|
type: 0 // conversation
|
|
})
|
|
}
|
|
return chat
|
|
}
|
|
|
|
async function sleep(ms) {
|
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
}
|
|
|
|
async function parseReceiveParams(payload) {
|
|
const dat = payload.content || payload
|
|
const sender_pub_key = dat.sender.pub_key
|
|
const chat_uuid = dat.chat.uuid
|
|
const chat_type = dat.chat.type
|
|
const chat_members: { [k: string]: any } = dat.chat.members || {}
|
|
const chat_name = dat.chat.name
|
|
const amount = dat.message.amount
|
|
const content = dat.message.content
|
|
const mediaToken = dat.message.mediaToken
|
|
const msg_id = dat.message.id||0
|
|
const mediaKey = dat.message.mediaKey
|
|
const mediaType = dat.message.mediaType
|
|
|
|
const isGroup = chat_type && chat_type == constants.chat_types.group
|
|
let sender
|
|
let chat
|
|
const owner = await models.Contact.findOne({ where: { isOwner: true } })
|
|
if (isGroup) {
|
|
sender = await models.Contact.findOne({ where: { publicKey: sender_pub_key } })
|
|
chat = await models.Chat.findOne({ where: { uuid: chat_uuid } })
|
|
} else {
|
|
sender = await findOrCreateContactByPubkey(sender_pub_key)
|
|
chat = await findOrCreateChatByUUID(
|
|
chat_uuid, [parseInt(owner.id), parseInt(sender.id)]
|
|
)
|
|
}
|
|
return { owner, sender, chat, sender_pub_key, chat_uuid, amount, content, mediaToken, mediaKey, mediaType, chat_type, msg_id, chat_members, chat_name }
|
|
}
|
|
|
|
export {
|
|
findOrCreateChat,
|
|
sendMessage,
|
|
sendContactKeys,
|
|
findOrCreateContactByPubkey,
|
|
findOrCreateChatByUUID,
|
|
sleep,
|
|
parseReceiveParams,
|
|
performKeysendMessage
|
|
}
|
|
|
|
async function asyncForEach(array, callback) {
|
|
for (let index = 0; index < array.length; index++) {
|
|
await callback(array[index], index, array);
|
|
}
|
|
}
|
|
|
|
function newmsg(type, chat, sender, message){
|
|
return {
|
|
type: type,
|
|
chat: {
|
|
uuid: chat.uuid,
|
|
...chat.name && { name: chat.name },
|
|
...chat.type && { type: chat.type },
|
|
...chat.members && { members: chat.members },
|
|
},
|
|
message: message,
|
|
// sender: {
|
|
// pub_key: sender.publicKey,
|
|
// // ...sender.contactKey && {contact_key: sender.contactKey}
|
|
// }
|
|
}
|
|
}
|
|
|
|
function newkeyexchangemsg(type, sender){
|
|
return {
|
|
type: type,
|
|
sender: {
|
|
// pub_key: sender.publicKey,
|
|
contact_key: sender.contactKey,
|
|
...sender.alias && {alias: sender.alias},
|
|
// ...sender.photoUrl && {photoUrl: sender.photoUrl}
|
|
}
|
|
}
|
|
}
|