UNPKG

@tak-ps/node-cot

Version:

Lightweight JavaScript library for parsing and manipulating TAK messages

238 lines (202 loc) 7 kB
import Util from '../utils/util.js' import CoT from '../cot.js'; import type JSONCoT from '../types/types.js'; import type { Static } from '@sinclair/typebox'; import { v4 as randomUUID } from 'uuid'; export type MissionChatMember = { uid: string; type?: string; } export type MissionChatInput = { from: MissionChatMember; mission: { name: string; id: string; guid?: string; }; senderCallsign: string; message: string; parent?: string; groupOwner?: boolean; messageId?: string; } export class MissionChat extends CoT { constructor(chat: MissionChatInput) { const messageId = chat.messageId || randomUUID(); const cot: Static<typeof JSONCoT> = { event: { _attributes: Util.cot_event_attr('b-t-f', 'h-g-i-g-o'), point: Util.cot_point(), detail: { __chat: { _attributes: { parent: chat.parent || 'DataSyncMissionsList', groupOwner: chat.groupOwner ? 'true' : 'false', messageId, chatroom: chat.mission.name, id: chat.mission.id, senderCallsign: chat.senderCallsign }, chatgrp: { _attributes: { uid0: chat.from.uid, uid1: chat.mission.id, id: chat.mission.id } } }, } } } cot.event._attributes.uid = `GeoChat.${chat.from.uid}.${chat.mission.id}.${messageId}`; if (!cot.event.detail) cot.event.detail = {}; cot.event.detail.link = { _attributes: { uid: chat.from.uid, type: chat.from.type || 'a-f-G', relation: 'p-p' } } cot.event.detail.remarks = { _attributes: { source: chat.from.uid, to: chat.mission.id, time: cot.event._attributes.time }, _text: chat.message } super(cot) const dest: Record<string, string> = { mission: chat.mission.name }; if (chat.mission.guid) dest['mission-guid'] = chat.mission.guid; this.addDest(dest); } } export type DirectChatMember = { uid: string; callsign: string; } export const DirectChatReceiptStatus = { delivered: 'b-t-f-d', read: 'b-t-f-r', pending: 'b-t-f-p', failed: 'b-t-f-s' } as const; export type DirectChatReceiptInput = { to: DirectChatMember; from: DirectChatMember; status: keyof typeof DirectChatReceiptStatus; messageId: string; parent?: string; chatroom?: string; groupOwner?: boolean; } /** * Delivery/Read Receipt for a DirectChat message * The `to` member is the sender of the original message that the receipt * refers to and `messageId` is the original message's messageId */ export class DirectChatReceipt extends CoT { constructor(receipt: DirectChatReceiptInput) { const type = DirectChatReceiptStatus[receipt.status]; const cot: Static<typeof JSONCoT> = { event: { _attributes: Util.cot_event_attr(type, 'h-g-i-g-o'), point: Util.cot_point(), detail: { __chatreceipt: { _attributes: { parent: receipt.parent || 'RootContactGroup', groupOwner: receipt.groupOwner ? 'true' : 'false', messageId: receipt.messageId, chatroom: receipt.chatroom || receipt.to.callsign, id: receipt.to.uid, senderCallsign: receipt.from.callsign }, chatgrp: { _attributes: { uid0: receipt.from.uid, uid1: receipt.to.uid, id: receipt.to.uid } } }, } } } // ATAK & WinTAK set the receipt Event UID to the original messageId and // ATAK looks the original message up by the receipt's Event UID on receive cot.event._attributes.uid = receipt.messageId; if (!cot.event.detail) cot.event.detail = {}; cot.event.detail.link = { _attributes: { uid: receipt.from.uid, type: 'a-f-G', relation: 'p-p' } } super(cot) this.addDest({ uid: receipt.to.uid }) } } export type DirectChatInput = { to: DirectChatMember; from: DirectChatMember; message: string; parent?: string; chatroom?: string; groupOwner?: boolean; messageId?: string; id?: string; } export class DirectChat extends CoT { constructor(chat: DirectChatInput) { const cot: Static<typeof JSONCoT> = { event: { _attributes: Util.cot_event_attr('b-t-f', 'h-g-i-g-o'), point: Util.cot_point(), detail: { __chat: { _attributes: { parent: chat.parent || 'RootContactGroup', groupOwner: chat.groupOwner ? 'true' : 'false', messageId: chat.messageId || randomUUID(), chatroom: chat.chatroom || chat.to.callsign, id: chat.to.uid, senderCallsign: chat.from.callsign }, chatgrp: { _attributes: { uid0: chat.from.uid, uid1: chat.to.uid, id: chat.to.uid } } }, } } } cot.event._attributes.uid = `GeoChat.${chat.from.uid}.${chat.to.uid}.${randomUUID()}`; if (!cot.event.detail) cot.event.detail = {}; cot.event.detail.link = { _attributes: { uid: chat.from.uid, type: 'a-f-G', relation: 'p-p' } } cot.event.detail.remarks = { _attributes: { source: chat.from.uid, to: chat.to.uid, time: cot.event._attributes.time }, _text: chat.message } super(cot) this.addDest({ uid: chat.to.uid }) } }