Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,5 @@ $RECYCLE.BIN/
# Windows shortcuts
*.lnk

.claude/*
# End of https://www.gitignore.io/api/node,linux,macos,windows
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
nodejs 16.14.0
nodejs 20.16.0
yarn 1.22.19
8 changes: 8 additions & 0 deletions libs/gql-schema/campaign.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export const schema = `
enum CampaignType {
SMS
CALL
}

input CampaignsFilter {
isArchived: Boolean
isStarted: Boolean
Expand Down Expand Up @@ -52,6 +57,7 @@ export const schema = `
type CampaignReadiness {
id: ID!
basics: Boolean!
campaignType: Boolean!
Comment thread
sukhada marked this conversation as resolved.
messagingService: Boolean!
textingHours: Boolean!
integration: Boolean!
Expand Down Expand Up @@ -128,6 +134,7 @@ export const schema = `
columnMapping: [CsvColumnMapping!]
messagingService: MessagingService
contactsFilename: String
campaignType: CampaignType!
}

type CampaignEdge {
Expand Down Expand Up @@ -201,6 +208,7 @@ export const schema = `
messagingServiceSid: String
autosendLimit: Int
columnMapping: [CsvColumnMappingInput!]
campaignType: CampaignType
}
`;
export default schema;
74 changes: 74 additions & 0 deletions libs/gql-schema/dialer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export const schema = `
type DialerCampaignContact {
id: ID!
campaignId: ID!
firstName: String!
lastName: String!
zip: String
callStatus: String!
doNotCall: Boolean!
attemptCount: Int!
lastAttemptedAt: Date
customFields: JSON!
assignment: Assignment
interactionSteps: [InteractionStep!]!
questionResponseValues: [DialerQuestionResponseValue!]!
tags: [Tag!]!
campaignVariables: [CampaignVariable!]!
}

type DialerQuestionResponseValue {
id: ID!
interactionStepId: ID!
question: String!
value: String!
}

# A past texting conversation with the same person (matched by phone), shown
# as context on the calling screen. One entry per prior campaign_contact.
type DialerContactConversation {
campaignId: ID!
campaignTitle: String!
contactId: ID!
firstName: String
lastName: String
messages: [Message!]!
}

type DialerCall {
id: ID!
dialerCampaignContactId: ID!
status: String!
fromNumber: String
telnyxCallControlId: String
createdAt: Date!
answeredAt: Date
endedAt: Date
}

type InitiateCallResult {
dialerCallId: ID!
contactPhone: String!
fromNumber: String!
}

type RequestCallShiftResult {
assignmentId: ID
campaignId: ID
count: Int!
}

input DialerQuestionResponseInput {
interactionStepId: String!
value: String!
}

input UpdateDialerCallInput {
status: String
telnyxCallControlId: String
answeredAt: String
endedAt: String
}
`;

export default schema;
14 changes: 13 additions & 1 deletion libs/gql-schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { schema as campaignGroupSchema } from "./campaign-group";
import { schema as campaignVariableSchema } from "./campaign-variable";
import { schema as cannedResponseSchema } from "./canned-response";
import { schema as conversationSchema } from "./conversations";
import { schema as dialerSchema } from "./dialer";
import { schema as externalActivistCodeSchema } from "./external-activist-code";
import { schema as externalListSchema } from "./external-list";
import { schema as externalResultCodeSchema } from "./external-result-code";
Expand Down Expand Up @@ -246,6 +247,10 @@ const rootSchema = `
type RootQuery {
currentUser: User
organization(id:String!, utc:String): Organization
getNextDialerContact(assignmentId: String!): DialerCampaignContact
getDialerContact(dialerCampaignContactId: String!): DialerCampaignContact
dialerContactTextingHistory(dialerCampaignContactId: String!): [DialerContactConversation!]!
callShiftAvailable(organizationId: String!): Boolean!
campaign(id:String!): Campaign
inviteByHash(hash:String!): [Invite]
contact(id:String!): CampaignContact
Expand Down Expand Up @@ -281,6 +286,12 @@ const rootSchema = `

type RootMutation {
createInvite(invite:InviteInput!): Invite
initiateCall(assignmentId: String!, dialerCampaignContactId: String!): InitiateCallResult!
updateDialerCall(dialerCallId: String!, input: UpdateDialerCallInput!): DialerCall!
saveDialerQuestionResponses(dialerCampaignContactId: String!, questionResponses: [DialerQuestionResponseInput!]!): DialerCampaignContact!
markDialerContactComplete(dialerCampaignContactId: String!, callStatus: String!): DialerCampaignContact!
tagDialerContact(dialerCampaignContactId: String!, tag: ContactTagActionInput!): DialerCampaignContact!
requestCallShift(organizationId: String!): RequestCallShiftResult!
createCampaign(campaign:CampaignInput!): Campaign
createTemplateCampaign(organizationId: String!): Campaign!
deleteTemplateCampaign(organizationId: String!, campaignId: String!): Boolean!
Expand Down Expand Up @@ -425,7 +436,8 @@ export const schema = [
externalResponseOptionSchema,
externalActivistCodeSchema,
externalResultCodeSchema,
externalSyncConfigSchema
externalSyncConfigSchema,
dialerSchema
];

export default rootSchema;
16 changes: 16 additions & 0 deletions libs/spoke-codegen/src/graphql/campaign-builder.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,19 @@ mutation StartCampaign($campaignId: String!) {
isApproved
}
}

query GetCampaignType($campaignId: String!) {
campaign(id: $campaignId) {
id
isStarted
campaignType
contactsCount
}
}

mutation EditCampaignType($campaignId: String!, $payload: CampaignInput!) {
editCampaign(id: $campaignId, campaign: $payload) {
id
campaignType
}
}
1 change: 1 addition & 0 deletions libs/spoke-codegen/src/graphql/campaign-list.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
fragment CampaignListEntry on Campaign {
id
title
campaignType
isStarted
isApproved
isArchived
Expand Down
1 change: 1 addition & 0 deletions libs/spoke-codegen/src/graphql/campaign-stats.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ query getCampaign($campaignId: String!) {
campaign(id: $campaignId) {
id
title
campaignType
dueBy
isArchived
isStarted
Expand Down
166 changes: 166 additions & 0 deletions libs/spoke-codegen/src/graphql/dialer.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
fragment DialerContactCore on DialerCampaignContact {
id
campaignId
firstName
lastName
zip
callStatus
doNotCall
attemptCount
lastAttemptedAt
customFields
campaignVariables {
id
name
value
}
questionResponseValues {
id
interactionStepId
question
value
}
tags {
id
title
description
confirmationSteps
onApplyScript
textColor
backgroundColor
isAssignable
isSystem
}
interactionSteps {
id
questionText
scriptOptions
answerOption
parentInteractionId
isDeleted
answerActions
question {
text
answerOptions {
value
nextInteractionStep {
id
scriptOptions
}
}
}
}
}

query GetNextDialerContact($assignmentId: String!) {
getNextDialerContact(assignmentId: $assignmentId) {
...DialerContactCore
}
}

query GetDialerContact($dialerCampaignContactId: String!) {
getDialerContact(dialerCampaignContactId: $dialerCampaignContactId) {
...DialerContactCore
}
}

query DialerContactTextingHistory($dialerCampaignContactId: String!) {
dialerContactTextingHistory(
dialerCampaignContactId: $dialerCampaignContactId
) {
contactId
campaignId
campaignTitle
firstName
lastName
messages {
id
text
isFromContact
createdAt
}
}
}

mutation InitiateCall($assignmentId: String!, $dialerCampaignContactId: String!) {
initiateCall(assignmentId: $assignmentId, dialerCampaignContactId: $dialerCampaignContactId) {
dialerCallId
contactPhone
fromNumber
}
}

mutation UpdateDialerCall(
$dialerCallId: String!
$input: UpdateDialerCallInput!
) {
updateDialerCall(dialerCallId: $dialerCallId, input: $input) {
id
status
telnyxCallControlId
answeredAt
endedAt
}
}

mutation SaveDialerQuestionResponses(
$dialerCampaignContactId: String!
$questionResponses: [DialerQuestionResponseInput!]!
) {
saveDialerQuestionResponses(
dialerCampaignContactId: $dialerCampaignContactId
questionResponses: $questionResponses
) {
...DialerContactCore
}
}

mutation MarkDialerContactComplete(
$dialerCampaignContactId: String!
$callStatus: String!
) {
markDialerContactComplete(
dialerCampaignContactId: $dialerCampaignContactId
callStatus: $callStatus
) {
id
callStatus
attemptCount
lastAttemptedAt
}
}

mutation TagDialerContact(
$dialerCampaignContactId: String!
$tag: ContactTagActionInput!
) {
tagDialerContact(
dialerCampaignContactId: $dialerCampaignContactId
tag: $tag
) {
id
tags {
id
title
description
confirmationSteps
onApplyScript
textColor
backgroundColor
isAssignable
isSystem
}
}
}

query CallShiftAvailable($organizationId: String!) {
callShiftAvailable(organizationId: $organizationId)
}

mutation RequestCallShift($organizationId: String!) {
requestCallShift(organizationId: $organizationId) {
assignmentId
campaignId
count
}
}
Loading
Loading