diff --git a/apps/docs/api-reference/contacts/create-contact.mdx b/apps/docs/api-reference/contacts/create-contact.mdx new file mode 100644 index 0000000..db7935f --- /dev/null +++ b/apps/docs/api-reference/contacts/create-contact.mdx @@ -0,0 +1,3 @@ +--- +openapi: post /v1/contactBooks/{contactBookId}/contacts +--- diff --git a/apps/docs/api-reference/contacts/get-contact.mdx b/apps/docs/api-reference/contacts/get-contact.mdx new file mode 100644 index 0000000..27f33db --- /dev/null +++ b/apps/docs/api-reference/contacts/get-contact.mdx @@ -0,0 +1,3 @@ +--- +openapi: get /v1/contactBooks/{contactBookId}/contacts/{contactId} +--- diff --git a/apps/docs/api-reference/contacts/update-contact.mdx b/apps/docs/api-reference/contacts/update-contact.mdx new file mode 100644 index 0000000..dcba8b5 --- /dev/null +++ b/apps/docs/api-reference/contacts/update-contact.mdx @@ -0,0 +1,3 @@ +--- +openapi: patch /v1/contactBooks/{contactBookId}/contacts/{contactId} +--- diff --git a/apps/docs/api-reference/openapi.json b/apps/docs/api-reference/openapi.json index a69d192..5441974 100644 --- a/apps/docs/api-reference/openapi.json +++ b/apps/docs/api-reference/openapi.json @@ -120,7 +120,7 @@ ], "responses": { "200": { - "description": "Retrieve the user", + "description": "Retrieve the email", "content": { "application/json": { "schema": { @@ -217,14 +217,14 @@ "enum": [ "QUEUED", "SENT", + "DELIVERY_DELAYED", "BOUNCED", + "REJECTED", + "RENDERING_FAILURE", "DELIVERED", "OPENED", "CLICKED", "COMPLAINED", - "REJECTED", - "RENDERING_FAILURE", - "DELIVERY_DELAYED", "FAILED" ] }, @@ -381,6 +381,217 @@ } } } + }, + "/v1/contactBooks/{contactBookId}/contacts": { + "post": { + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 3, + "example": "cuiwqdj74rygf74" + }, + "required": true, + "name": "contactBookId", + "in": "path" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "email": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "subscribed": { + "type": "boolean" + } + }, + "required": [ + "email" + ] + } + } + } + }, + "responses": { + "200": { + "description": "Retrieve the user", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "contactId": { + "type": "string" + } + } + } + } + } + } + } + } + }, + "/v1/contactBooks/{contactBookId}/contacts/{contactId}": { + "patch": { + "parameters": [ + { + "schema": { + "type": "string", + "example": "cuiwqdj74rygf74" + }, + "required": true, + "name": "contactBookId", + "in": "path" + }, + { + "schema": { + "type": "string", + "example": "cuiwqdj74rygf74" + }, + "required": true, + "name": "contactId", + "in": "path" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "subscribed": { + "type": "boolean" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Retrieve the user", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "contactId": { + "type": "string" + } + } + } + } + } + } + } + }, + "get": { + "parameters": [ + { + "schema": { + "type": "string", + "example": "cuiwqdj74rygf74" + }, + "required": true, + "name": "contactBookId", + "in": "path" + }, + { + "schema": { + "type": "string", + "example": "cuiwqdj74rygf74" + }, + "required": true, + "name": "contactId", + "in": "path" + } + ], + "responses": { + "200": { + "description": "Retrieve the contact", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "firstName": { + "type": "string", + "nullable": true + }, + "lastName": { + "type": "string", + "nullable": true + }, + "email": { + "type": "string" + }, + "subscribed": { + "type": "boolean", + "default": true + }, + "properties": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "contactBookId": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "updatedAt": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "properties", + "contactBookId", + "createdAt", + "updatedAt" + ] + } + } + } + } + } + } } } } \ No newline at end of file diff --git a/apps/docs/mint.json b/apps/docs/mint.json index f9bc67a..ae0e087 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -72,6 +72,14 @@ "api-reference/emails/send-email" ] }, + { + "group": "Contacts", + "pages": [ + "api-reference/contacts/get-contact", + "api-reference/contacts/create-contact", + "api-reference/contacts/update-contact" + ] + }, { "group": "Domains", "pages": [ diff --git a/apps/web/src/server/service/email-queue-service.ts b/apps/web/src/server/service/email-queue-service.ts index aaf853d..c90109d 100644 --- a/apps/web/src/server/service/email-queue-service.ts +++ b/apps/web/src/server/service/email-queue-service.ts @@ -5,7 +5,6 @@ import { getConfigurationSetName } from "~/utils/ses-utils"; import { db } from "../db"; import { sendEmailThroughSes, sendEmailWithAttachments } from "../aws/ses"; import { getRedis } from "../redis"; -import { createUnsubUrl } from "./campaign-service"; function createQueueAndWorker(region: string, quota: number, suffix: string) { const connection = getRedis(); diff --git a/packages/sdk/src/contact.ts b/packages/sdk/src/contact.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/sdk/types/schema.d.ts b/packages/sdk/types/schema.d.ts index 8af3a3b..2d27de8 100644 --- a/packages/sdk/types/schema.d.ts +++ b/packages/sdk/types/schema.d.ts @@ -54,7 +54,7 @@ export interface paths { }; }; responses: { - /** @description Retrieve the user */ + /** @description Retrieve the email */ 200: { content: { "application/json": { @@ -73,7 +73,7 @@ export interface paths { emailEvents: ({ emailId: string; /** @enum {string} */ - status: "QUEUED" | "SENT" | "BOUNCED" | "DELIVERED" | "OPENED" | "CLICKED" | "COMPLAINED" | "REJECTED" | "RENDERING_FAILURE" | "DELIVERY_DELAYED" | "FAILED"; + status: "QUEUED" | "SENT" | "DELIVERY_DELAYED" | "BOUNCED" | "REJECTED" | "RENDERING_FAILURE" | "DELIVERED" | "OPENED" | "CLICKED" | "COMPLAINED" | "FAILED"; createdAt: string; data?: unknown; })[]; @@ -115,6 +115,99 @@ export interface paths { }; }; }; + "/v1/contactBooks/{contactBookId}/contacts": { + post: { + parameters: { + path: { + contactBookId: string; + }; + }; + requestBody: { + content: { + "application/json": { + email: string; + firstName?: string; + lastName?: string; + properties?: { + [key: string]: string; + }; + subscribed?: boolean; + }; + }; + }; + responses: { + /** @description Retrieve the user */ + 200: { + content: { + "application/json": { + contactId?: string; + }; + }; + }; + }; + }; + }; + "/v1/contactBooks/{contactBookId}/contacts/{contactId}": { + get: { + parameters: { + path: { + contactBookId: string; + contactId: string; + }; + }; + responses: { + /** @description Retrieve the contact */ + 200: { + content: { + "application/json": { + id: string; + firstName?: string | null; + lastName?: string | null; + email: string; + /** @default true */ + subscribed?: boolean; + properties: { + [key: string]: string; + }; + contactBookId: string; + createdAt: string; + updatedAt: string; + }; + }; + }; + }; + }; + patch: { + parameters: { + path: { + contactBookId: string; + contactId: string; + }; + }; + requestBody: { + content: { + "application/json": { + firstName?: string; + lastName?: string; + properties?: { + [key: string]: string; + }; + subscribed?: boolean; + }; + }; + }; + responses: { + /** @description Retrieve the user */ + 200: { + content: { + "application/json": { + contactId?: string; + }; + }; + }; + }; + }; + }; } export type webhooks = Record;