import formatMessage from 'format-message' ; import { RcVDialInNumberObj } from '@ringcentral-integration/commons/interfaces/Rcv.model' ; import { formatMeetingId } from './formatMeetingId' ; import i18n from './i18n' ; import { CommonBrand , DialInSectionParams , FormatToHtmlOptions , ParcelledLink , RcmMainParams , RcvMainParams , TplResult , } from './index.interface' ; function formatSmartphones ( dialInNumber , pinNumber , showMeetingPasswordPSTN , meetingPasswordPSTN ) { if ( ! dialInNumber || dialInNumber . length === 0 ) { return '' ; } if ( typeof dialInNumber === 'string' ) { return `${ dialInNumber },,${ pinNumber }#${ showMeetingPasswordPSTN ? `,,${ meetingPasswordPSTN }#` : '' }` ; } return dialInNumber . map ( ( obj ) => { const passwordField = showMeetingPasswordPSTN ? `,,${ meetingPasswordPSTN }#` : '' ; const locationField = obj ?. country ?. name && obj . location ? `${ obj . country . name } (${ obj . location })` : obj ?. country ?. name || '' ; return `${ obj . phoneNumber },,${ pinNumber }#${ passwordField } ${ locationField }` ; } ) . join ( '\n\t' ) ; } function formatDialInNumber ( dialInNumber ) { if ( ! dialInNumber || dialInNumber . length === 0 ) { return '' ; } if ( typeof dialInNumber === 'string' ) { return dialInNumber ; } return dialInNumber . map ( ( obj ) => { const locationField = obj ?. country ?. name && obj . location ? `${ obj . country . name } (${ obj . location })` : obj ?. country ?. name || '' ; return `${ obj . phoneNumber } ${ locationField }` ; } ) . join ( '\n\t' ) ; } function getPasswordTpl ( meetingPassword , currentLocale ) { const passwordLiteral = i18n . getString ( 'password' , currentLocale ) ; return meetingPassword ? `${ passwordLiteral }: ${ meetingPassword }` : '' ; } param input function replaceTextLinksToAnchors ( input ) { /**
     * [^<>\]]+ means should match any characters except < or > or ]
     * (?!\s*<\/a>) means url should not be followed by either "</a>" or "     </a>"
     * (?!"[^>]*>) means url should not followed by ">
     * further explanation: origin string: <a href="http://www.example.com">http://www.example.com </a> should not match
     * (?=[\s!,?\]]|$) means url can be followed by punctuations or whitespace or nothing
     */ const pattern = /(?:(?:ht|f)tps?:\/\/|www)[^<>\]]+(?!\s*<\/a>)(?!"[^>]*>)(?=[\s!,?\]<]|$)/gim ; return input . replace ( pattern , ( $0 ) : string => { return `<a target="_blank" href="${ $0 }">${ $0 }</a>` ; } ) ; } const htmlNewLine = '<br>' ; const htmlIndentation = '&nbsp;' ; const htmlTabIndentation = htmlIndentation . repeat ( 4 ) ; function formatTextToHtml ( plantText , options = { } ) { const { links = [ ] , uselessSentences = [ ] , searchLinks = false , newLine = htmlNewLine , indentation = htmlIndentation , tabIndentation = htmlTabIndentation , } = options ; let htmlContent = plantText . replace ( /\r\n|\n|\r/g , '\n' ) . split ( '\n' ) . map ( ( line ) => { return line . replace ( /\t/g , tabIndentation ) . replace ( /^\s*/ , ( $0 ) => indentation . repeat ( $0 . length ) ) ; } ) . join ( newLine ) ; uselessSentences . forEach ( ( sentence ) => { if ( sentence ) { htmlContent = htmlContent . replace ( sentence , '' ) ; } } ) ; links . forEach ( ( link ) => { if ( link ) { const isPlantLink = typeof link === 'string' ; const uri = isPlantLink ? ( link as string ) : ( link as ParcelledLink ) . uri ; const text = isPlantLink ? ( link as string ) : ( link as ParcelledLink ) . text ; if ( uri && text ) { htmlContent = htmlContent . replace ( uri , `<a target="_blank" href="${ uri }">${ text }</a>` ) ; } } } ) ; if ( searchLinks ) { htmlContent = replaceTextLinksToAnchors ( htmlContent ) ; } return htmlContent ; } /**
 * Dial-in password: ${passwordPstn}
 */ function getRcvPstnPasswordTpl ( meetingPasswordPSTN , currentLocale ) { const passwordPstnLiteral = i18n . getString ( 'passwordPstn' , currentLocale ) ; return `${ passwordPstnLiteral } ${ meetingPasswordPSTN }` ; } function getBaseRcmTpl ( { meeting , serviceInfo , extensionInfo , invitationInfo } , brand , currentLocale ) { const accountName = extensionInfo . name ; const meetingId = meeting . id ; const joinUri = meeting . links . joinUri ; const password = meeting . password ; const mobileDialingNumberTpl = serviceInfo . mobileDialingNumberTpl ; const phoneDialingNumberTpl = serviceInfo . phoneDialingNumberTpl ; const passwordTpl = getPasswordTpl ( password , currentLocale ) ; const teleconference = brand . brandConfig . teleconference ; let formattedMsg = invitationInfo ?. invitation ; if ( ! formattedMsg ) { formattedMsg = formatMessage ( i18n . getString ( 'inviteMeetingContent' , currentLocale ) , { accountName , brandName : brand . name , joinUri , passwordTpl , mobileDialingNumberTpl , phoneDialingNumberTpl , meetingId : formatMeetingId ( meetingId ) , teleconference , } ) ; } return { formattedMsg , links : { joinUri , teleconference , } , } ; } function getRcmEventTpl ( mainInfo , brand , currentLocale ) { const tplResult = getBaseRcmTpl ( mainInfo , brand , currentLocale ) ; return tplResult . formattedMsg ; } function getRcmHtmlEventTpl ( mainInfo , brand , currentLocale ) { const tplResult = getBaseRcmTpl ( mainInfo , brand , currentLocale ) ; return formatTextToHtml ( tplResult . formattedMsg , { links : [ tplResult . links . joinUri , tplResult . links . teleconference ] , } ) ; } function formatDialInSection ( { dialInNumber , isMeetingSecret , meetingPasswordPSTN , shortId , currentLocale , } ) { const dialingString = i18n . getString ( typeof dialInNumber === 'string' ? 'rcvInviteMeetingContentDial' : 'rcvInviteMeetingContentCountryDial' , currentLocale ) ; const showMeetingPasswordPSTN = ! ! ( isMeetingSecret && meetingPasswordPSTN ) ; const dialingInfo = formatMessage ( dialingString , { smartphones : formatSmartphones ( dialInNumber , shortId , showMeetingPasswordPSTN , meetingPasswordPSTN ) , dialNumber : formatDialInNumber ( dialInNumber ) , pinNumber : formatMeetingId ( shortId ) , } ) ; const pstnPasswordTpl = ! showMeetingPasswordPSTN ? '' : getRcvPstnPasswordTpl ( meetingPasswordPSTN , currentLocale ) ; return `${ dialingInfo }${ pstnPasswordTpl }` ; } function getRcvDialInInfo ( { rcvTeleconference , ... args } ) { const hasDialInNumber = args ?. dialInNumber ?. length > 0 ; const dialInSection = hasDialInNumber ? formatDialInSection ( args ) : '' ; const teleconferenceInfo = formatMessage ( i18n . getString ( 'rcvTeleconference' , args . currentLocale ) , { teleconference : rcvTeleconference , } ) ; return `${ dialInSection }${ teleconferenceInfo }` ; } function getBaseRcvTpl ( { meeting , extensionInfo , dialInNumber , invitationInfo } , brand , currentLocale , enableRcvConnector = false , enableE2EE = false ) { const joinUri = meeting . joinUri ; const teleconference = brand . rcvTeleconference ; if ( invitationInfo ) { return { formattedMsg : invitationInfo , links : { joinUri , teleconference , } , } ; } const accountName = extensionInfo . name ; const { meetingPassword , meetingPasswordPSTN , isMeetingSecret , e2ee } = meeting ; const meetingContent = [ ] ; const showMeetingPasswordPSTN = ! ! ( isMeetingSecret && meetingPasswordPSTN ) ; if ( enableE2EE && e2ee ) { meetingContent . push ( i18n . getString ( 'rcvE2EEInviteMeetingContent' , currentLocale ) ) ; return { formattedMsg : formatMessage ( meetingContent . join ( '' ) , { accountName , brandName : brand . name , rcvProductName : brand . brandConfig . rcvProductName , joinUri , e2EESupportLinkText : formatMessage ( i18n . getString ( 'e2EESupportLinkText' , currentLocale ) , { brandName : brand . name , } ) , rcvE2EESupportUrl : brand . rcvE2EESupportUrl , } ) , links : { joinUri , teleconference , } , } ; } meetingContent . push ( brand . brandConfig . rcvInviteMeetingContent as string ) ; if ( dialInNumber && dialInNumber . length > 0 ) { meetingContent . push ( i18n . getString ( typeof dialInNumber === 'string' ? 'rcvInviteMeetingContentDial' : 'rcvInviteMeetingContentCountryDial' , currentLocale ) ) ; if ( showMeetingPasswordPSTN ) { meetingContent . push ( getRcvPstnPasswordTpl ( meetingPasswordPSTN , currentLocale ) ) ; } } meetingContent . push ( `${ i18n . getString ( 'rcvTeleconference' , currentLocale ) }` ) ; const passwordTpl = isMeetingSecret ? getPasswordTpl ( meetingPassword , currentLocale ) : '' ; if ( enableRcvConnector ) { meetingContent . push ( `${ i18n . getString ( 'rcvSipHeader' , currentLocale ) }` ) ; const rcvSipContent = isMeetingSecret ? 'rcvSipContentWithPwd' : 'rcvSipContentNoPwd' ; meetingContent . push ( `${ i18n . getString ( rcvSipContent , currentLocale ) }` ) ; } const shortId = meeting . shortId ; const formattedMsg = formatMessage ( meetingContent . join ( '' ) , { accountName , brandName : brand . brandConfig . rcvBrandName ?? brand . name , joinUri , passwordTpl , meetingPasswordPSTN , meetingId : shortId , pinNumber : formatMeetingId ( shortId ) , teleconference , dialNumber : formatDialInNumber ( dialInNumber ) , smartphones : formatSmartphones ( dialInNumber , shortId , showMeetingPasswordPSTN , meetingPasswordPSTN ) , rcvProductName : brand . brandConfig . rcvProductName , } ) ; return { formattedMsg , links : { joinUri , teleconference , } , } ; } function getRcvEventTpl ( mainInfo , brand , currentLocale , enableRcvConnector = false , enableE2EE = false ) { const tplResult = getBaseRcvTpl ( mainInfo , brand , currentLocale , enableRcvConnector , enableE2EE ) ; return tplResult . formattedMsg ; } function getRcvHtmlEventTpl ( mainInfo , brand , currentLocale , enableRcvConnector = false , enableE2EE = false ) { const tplResult = getBaseRcvTpl ( mainInfo , brand , currentLocale , enableRcvConnector , enableE2EE ) ; const links = [ tplResult . links . joinUri , tplResult . links . teleconference , { uri : brand . rcvE2EESupportUrl , text : formatMessage ( i18n . getString ( 'e2EESupportLinkText' , currentLocale ) , { brandName : brand . name , } ) , } , ] ; return formatTextToHtml ( tplResult . formattedMsg , { uselessSentences : [ `${ formatMessage ( i18n . getString ( 'e2EESupportLinkText' , currentLocale ) , { brandName : brand . name , } ) }<br>` , ] , links , } ) ; } function getMeetingId ( meetingUri , rcvUriRegExp , rcmUriRegExp ) { if ( meetingUri ) { const regs = [ rcmUriRegExp , rcvUriRegExp ] ; for ( let i = 0 ; i < regs . length ; i += 1 ) { const matches = regs [ i ] . exec ( meetingUri ) ; if ( matches && matches . length > 0 ) { const match0 = matches [ 0 ] ; const link = ( match0 . indexOf ( '?' ) > - 1 ? matches [ 0 ] . substring ( 0 , matches [ 0 ] . indexOf ( '?' ) ) : match0 ) . split ( '/' ) ; const id = link [ link . length - 1 ] ; return id ; } } } return null ; } function stripMeetingLinks ( text , rcvUriRegExp , rcmUriRegExp ) { let result = text ; [ rcmUriRegExp , rcvUriRegExp ] . forEach ( ( reg ) => { while ( reg . test ( result ) ) { result = result . replace ( reg , '' ) ; } } ) ; return result ; } function meetingLinkContains ( rcvUriRegExp , rcmUriRegExp , text ? ) { return { hasRCM : rcmUriRegExp . test ( text ?? '' ) , hasRCV : rcvUriRegExp . test ( text ?? '' ) , } ; } export { getBaseRcvTpl , formatMeetingId , formatTextToHtml , getMeetingId , getRcmEventTpl , getRcmHtmlEventTpl , getRcvDialInInfo , getRcvEventTpl , getRcvHtmlEventTpl , htmlIndentation , htmlNewLine , htmlTabIndentation , meetingLinkContains , replaceTextLinksToAnchors , stripMeetingLinks , } ;