import type { Tickets } from "node-zendesk" ; import { getLogger } from "@cocalc/backend/logger" ; import siteURL from "@cocalc/server/settings/site-url" ; import getName , { getNameByEmail } from "@cocalc/server/accounts/get-name" ; import getClient from "./zendesk-client" ; import { urlToUserURL } from "./util" ; const log = getLogger ( "support:create-ticket" ) ; interface Options { email : string ; account_id ? : string ; files ? : { project_id : string ; path ? : string ; } [ ] ; type ? : "bug" | "question" ; subject ? : string ; body ? : string ; url ? : string ; info ? : { userAgent ? : string ; browser ? : string ; } ; } export default async function createTicket ( options ) { log . debug ( "createTicket" , options ) ; const client = await getClient ( ) ; const { account_id , email , files , type , subject , url , info } = options ; const user = await getUser ( email , account_id ) ; const userResult = await client . users . createOrUpdate ( user ) ; let { body } = options ; if ( url ) { body += `\n\n\nURL:\n${ url }\n` ; } if ( files && files . length > 0 ) { body += "\n\n\nRELEVANT FILES:\n\n" ; for ( const file of files ) { body += `\n\n- ${ await toURL ( file ) }\n` ; } } if ( info ) { body += "\n\n\nBROWSER INFO:\n\n" ; body += `\n\n- userAgent="${ info . userAgent }"` ; body += `\n\n- browser="${ info . browser }"` ; } body += "\n\n\nUSER:\n\n" ; body += `\n\n- account_id="${ account_id }"` ; body += `\n\n- email="${ email }"` ; const ticket = { ticket : { comment : { body } , external_id : account_id , subject , type : type as Tickets . TicketType , requester_id : userResult . id , } , } ; log . debug ( "ticket " , ticket ) ; const ticketResult = await client . tickets . create ( ticket ) ; log . debug ( "got " , { ticketResult } ) ; return urlToUserURL ( ticketResult . url ) ; } async function toURL ( { project_id , path , } ) { let s = ( await siteURL ( ) ) + "/" + encodeURI ( `projects/${ project_id }` ) ; if ( ! path ) return s ; return s + encodeURI ( `/files/${ path }` ) ; } async function getUser ( email , account_id ? ) { let name = undefined ; if ( account_id ) { name = await getName ( account_id ) ; } if ( ! name ) { name = await getNameByEmail ( email ) ; } if ( ! name ?. trim ( ) ) { name = email ; } return { user : { name , email , external_id : account_id ?? null } , } ; }