+
-
+
Upload image
@@ -188,10 +194,17 @@ export const SettingsPopup: FC<{ getRef?: Ref
}> = (props) => {
+ {enabledOpenaiSelf && (
+
+
+
+ )}
{!getRef && (
-
+
)}
{!!user?.tier?.team_members && isGeneral &&
}
diff --git a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts
index f2306dba..153e4323 100644
--- a/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts
+++ b/libraries/nestjs-libraries/src/database/prisma/integrations/integration.service.ts
@@ -54,9 +54,11 @@ export class IntegrationService {
timezone?: number,
customInstanceDetails?: string
) {
+ console.log('XXXX UPLOADING');
const uploadedPicture = picture
? await this.storage.uploadSimple(picture)
: undefined;
+ console.log('XXXX UPLOAD DONE');
return this._integrationRepository.createOrUpdateIntegration(
org,
name,
@@ -408,7 +410,7 @@ export class IntegrationService {
}) {
const getPlugById = await this._integrationRepository.getPlug(data.plugId);
if (!getPlugById) {
- return ;
+ return;
}
const integration = this._integrationManager.getSocialIntegration(
@@ -434,11 +436,11 @@ export class IntegrationService {
);
if (process) {
- return ;
+ return;
}
if (data.totalRuns === data.currentRun) {
- return ;
+ return;
}
this._workerServiceProducer.emit('plugs', {
diff --git a/libraries/nestjs-libraries/src/database/prisma/migrations/20241213183825_add_open_aiapi_key_to_user/migration.sql b/libraries/nestjs-libraries/src/database/prisma/migrations/20241213183825_add_open_aiapi_key_to_user/migration.sql
new file mode 100644
index 00000000..581c34f3
--- /dev/null
+++ b/libraries/nestjs-libraries/src/database/prisma/migrations/20241213183825_add_open_aiapi_key_to_user/migration.sql
@@ -0,0 +1,727 @@
+-- CreateEnum
+CREATE TYPE "OrderStatus" AS ENUM ('PENDING', 'ACCEPTED', 'CANCELED', 'COMPLETED');
+
+-- CreateEnum
+CREATE TYPE "From" AS ENUM ('BUYER', 'SELLER');
+
+-- CreateEnum
+CREATE TYPE "State" AS ENUM ('QUEUE', 'PUBLISHED', 'ERROR', 'DRAFT');
+
+-- CreateEnum
+CREATE TYPE "SubscriptionTier" AS ENUM ('STANDARD', 'PRO', 'TEAM', 'ULTIMATE');
+
+-- CreateEnum
+CREATE TYPE "Period" AS ENUM ('MONTHLY', 'YEARLY');
+
+-- CreateEnum
+CREATE TYPE "Provider" AS ENUM ('LOCAL', 'GITHUB', 'GOOGLE');
+
+-- CreateEnum
+CREATE TYPE "Role" AS ENUM ('SUPERADMIN', 'ADMIN', 'USER');
+
+-- CreateEnum
+CREATE TYPE "APPROVED_SUBMIT_FOR_ORDER" AS ENUM ('NO', 'WAITING_CONFIRMATION', 'YES');
+
+-- CreateTable
+CREATE TABLE "Organization" (
+ "id" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "description" TEXT,
+ "paymentId" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Organization_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "User" (
+ "id" TEXT NOT NULL,
+ "email" TEXT NOT NULL,
+ "password" TEXT,
+ "providerName" "Provider" NOT NULL,
+ "name" TEXT,
+ "lastName" TEXT,
+ "isSuperAdmin" BOOLEAN NOT NULL DEFAULT false,
+ "bio" TEXT,
+ "openAIAPIKey" TEXT,
+ "audience" INTEGER NOT NULL DEFAULT 0,
+ "pictureId" TEXT,
+ "providerId" TEXT,
+ "timezone" INTEGER NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "lastReadNotifications" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "inviteId" TEXT,
+ "activated" BOOLEAN NOT NULL DEFAULT true,
+ "marketplace" BOOLEAN NOT NULL DEFAULT true,
+ "account" TEXT,
+ "connectedAccount" BOOLEAN NOT NULL DEFAULT false,
+ "lastOnline" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "UsedCodes" (
+ "id" TEXT NOT NULL,
+ "code" TEXT NOT NULL,
+ "orgId" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "UsedCodes_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "UserOrganization" (
+ "id" TEXT NOT NULL,
+ "userId" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "disabled" BOOLEAN NOT NULL DEFAULT false,
+ "role" "Role" NOT NULL DEFAULT 'USER',
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "UserOrganization_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "GitHub" (
+ "id" TEXT NOT NULL,
+ "login" TEXT,
+ "name" TEXT,
+ "token" TEXT NOT NULL,
+ "jobId" TEXT,
+ "organizationId" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "GitHub_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Trending" (
+ "id" TEXT NOT NULL,
+ "trendingList" TEXT NOT NULL,
+ "language" TEXT,
+ "hash" TEXT NOT NULL,
+ "date" TIMESTAMP(3) NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Trending_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "TrendingLog" (
+ "id" TEXT NOT NULL,
+ "language" TEXT,
+ "date" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "TrendingLog_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "ItemUser" (
+ "id" TEXT NOT NULL,
+ "userId" TEXT NOT NULL,
+ "key" TEXT NOT NULL,
+
+ CONSTRAINT "ItemUser_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Star" (
+ "id" TEXT NOT NULL,
+ "stars" INTEGER NOT NULL,
+ "totalStars" INTEGER NOT NULL,
+ "forks" INTEGER NOT NULL,
+ "totalForks" INTEGER NOT NULL,
+ "login" TEXT NOT NULL,
+ "date" DATE NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Star_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Media" (
+ "id" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "path" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Media_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SocialMediaAgency" (
+ "id" TEXT NOT NULL,
+ "userId" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "logoId" TEXT,
+ "website" TEXT,
+ "slug" TEXT,
+ "facebook" TEXT,
+ "instagram" TEXT,
+ "twitter" TEXT,
+ "linkedIn" TEXT,
+ "youtube" TEXT,
+ "tiktok" TEXT,
+ "otherSocialMedia" TEXT,
+ "shortDescription" TEXT NOT NULL,
+ "description" TEXT NOT NULL,
+ "approved" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "SocialMediaAgency_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "SocialMediaAgencyNiche" (
+ "agencyId" TEXT NOT NULL,
+ "niche" TEXT NOT NULL,
+
+ CONSTRAINT "SocialMediaAgencyNiche_pkey" PRIMARY KEY ("agencyId","niche")
+);
+
+-- CreateTable
+CREATE TABLE "Credits" (
+ "id" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "credits" INTEGER NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Credits_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Subscription" (
+ "id" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "subscriptionTier" "SubscriptionTier" NOT NULL,
+ "identifier" TEXT,
+ "cancelAt" TIMESTAMP(3),
+ "period" "Period" NOT NULL,
+ "totalChannels" INTEGER NOT NULL,
+ "isLifetime" BOOLEAN NOT NULL DEFAULT false,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Subscription_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Customer" (
+ "id" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "orgId" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Customer_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Integration" (
+ "id" TEXT NOT NULL,
+ "internalId" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "picture" TEXT,
+ "providerIdentifier" TEXT NOT NULL,
+ "type" TEXT NOT NULL,
+ "token" TEXT NOT NULL,
+ "disabled" BOOLEAN NOT NULL DEFAULT false,
+ "tokenExpiration" TIMESTAMP(3),
+ "refreshToken" TEXT,
+ "profile" TEXT,
+ "deletedAt" TIMESTAMP(3),
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3),
+ "inBetweenSteps" BOOLEAN NOT NULL DEFAULT false,
+ "refreshNeeded" BOOLEAN NOT NULL DEFAULT false,
+ "postingTimes" TEXT NOT NULL DEFAULT '[{"time":120}, {"time":400}, {"time":700}]',
+ "customInstanceDetails" TEXT,
+ "customerId" TEXT,
+
+ CONSTRAINT "Integration_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Comments" (
+ "id" TEXT NOT NULL,
+ "content" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "userId" TEXT NOT NULL,
+ "date" TIMESTAMP(3) NOT NULL,
+ "parentCommentId" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Comments_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Post" (
+ "id" TEXT NOT NULL,
+ "state" "State" NOT NULL DEFAULT 'QUEUE',
+ "publishDate" TIMESTAMP(3) NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "integrationId" TEXT NOT NULL,
+ "content" TEXT NOT NULL,
+ "group" TEXT NOT NULL,
+ "title" TEXT,
+ "description" TEXT,
+ "parentPostId" TEXT,
+ "releaseId" TEXT,
+ "releaseURL" TEXT,
+ "settings" TEXT,
+ "image" TEXT,
+ "submittedForOrderId" TEXT,
+ "submittedForOrganizationId" TEXT,
+ "approvedSubmitForOrder" "APPROVED_SUBMIT_FOR_ORDER" NOT NULL DEFAULT 'NO',
+ "lastMessageId" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Notifications" (
+ "id" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "content" TEXT NOT NULL,
+ "link" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Notifications_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "MessagesGroup" (
+ "id" TEXT NOT NULL,
+ "buyerOrganizationId" TEXT NOT NULL,
+ "buyerId" TEXT NOT NULL,
+ "sellerId" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "MessagesGroup_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "PayoutProblems" (
+ "id" TEXT NOT NULL,
+ "status" TEXT NOT NULL,
+ "orderId" TEXT NOT NULL,
+ "userId" TEXT NOT NULL,
+ "postId" TEXT,
+ "amount" INTEGER NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "PayoutProblems_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Orders" (
+ "id" TEXT NOT NULL,
+ "buyerId" TEXT NOT NULL,
+ "sellerId" TEXT NOT NULL,
+ "status" "OrderStatus" NOT NULL,
+ "messageGroupId" TEXT NOT NULL,
+ "captureId" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "Orders_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "OrderItems" (
+ "id" TEXT NOT NULL,
+ "orderId" TEXT NOT NULL,
+ "integrationId" TEXT NOT NULL,
+ "quantity" INTEGER NOT NULL,
+ "price" INTEGER NOT NULL,
+
+ CONSTRAINT "OrderItems_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Messages" (
+ "id" TEXT NOT NULL,
+ "from" "From" NOT NULL,
+ "content" TEXT,
+ "groupId" TEXT NOT NULL,
+ "special" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "deletedAt" TIMESTAMP(3),
+
+ CONSTRAINT "Messages_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Plugs" (
+ "id" TEXT NOT NULL,
+ "organizationId" TEXT NOT NULL,
+ "plugFunction" TEXT NOT NULL,
+ "data" TEXT NOT NULL,
+ "integrationId" TEXT NOT NULL,
+ "activated" BOOLEAN NOT NULL DEFAULT true,
+
+ CONSTRAINT "Plugs_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "ExisingPlugData" (
+ "id" TEXT NOT NULL,
+ "integrationId" TEXT NOT NULL,
+ "methodName" TEXT NOT NULL,
+ "value" TEXT NOT NULL,
+
+ CONSTRAINT "ExisingPlugData_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE INDEX "User_lastReadNotifications_idx" ON "User"("lastReadNotifications");
+
+-- CreateIndex
+CREATE INDEX "User_inviteId_idx" ON "User"("inviteId");
+
+-- CreateIndex
+CREATE INDEX "User_account_idx" ON "User"("account");
+
+-- CreateIndex
+CREATE INDEX "User_lastOnline_idx" ON "User"("lastOnline");
+
+-- CreateIndex
+CREATE INDEX "User_pictureId_idx" ON "User"("pictureId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "User_email_providerName_key" ON "User"("email", "providerName");
+
+-- CreateIndex
+CREATE INDEX "UsedCodes_code_idx" ON "UsedCodes"("code");
+
+-- CreateIndex
+CREATE INDEX "UserOrganization_disabled_idx" ON "UserOrganization"("disabled");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "UserOrganization_userId_organizationId_key" ON "UserOrganization"("userId", "organizationId");
+
+-- CreateIndex
+CREATE INDEX "GitHub_login_idx" ON "GitHub"("login");
+
+-- CreateIndex
+CREATE INDEX "GitHub_organizationId_idx" ON "GitHub"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Trending_hash_idx" ON "Trending"("hash");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Trending_language_key" ON "Trending"("language");
+
+-- CreateIndex
+CREATE INDEX "ItemUser_userId_idx" ON "ItemUser"("userId");
+
+-- CreateIndex
+CREATE INDEX "ItemUser_key_idx" ON "ItemUser"("key");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "ItemUser_userId_key_key" ON "ItemUser"("userId", "key");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Star_login_date_key" ON "Star"("login", "date");
+
+-- CreateIndex
+CREATE INDEX "Media_organizationId_idx" ON "Media"("organizationId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "SocialMediaAgency_userId_key" ON "SocialMediaAgency"("userId");
+
+-- CreateIndex
+CREATE INDEX "SocialMediaAgency_userId_idx" ON "SocialMediaAgency"("userId");
+
+-- CreateIndex
+CREATE INDEX "SocialMediaAgency_deletedAt_idx" ON "SocialMediaAgency"("deletedAt");
+
+-- CreateIndex
+CREATE INDEX "SocialMediaAgency_id_idx" ON "SocialMediaAgency"("id");
+
+-- CreateIndex
+CREATE INDEX "Credits_organizationId_idx" ON "Credits"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Credits_createdAt_idx" ON "Credits"("createdAt");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Subscription_organizationId_key" ON "Subscription"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Subscription_organizationId_idx" ON "Subscription"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Subscription_deletedAt_idx" ON "Subscription"("deletedAt");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Customer_orgId_name_deletedAt_key" ON "Customer"("orgId", "name", "deletedAt");
+
+-- CreateIndex
+CREATE INDEX "Integration_updatedAt_idx" ON "Integration"("updatedAt");
+
+-- CreateIndex
+CREATE INDEX "Integration_deletedAt_idx" ON "Integration"("deletedAt");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Integration_organizationId_internalId_key" ON "Integration"("organizationId", "internalId");
+
+-- CreateIndex
+CREATE INDEX "Comments_createdAt_idx" ON "Comments"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "Comments_organizationId_idx" ON "Comments"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Comments_date_idx" ON "Comments"("date");
+
+-- CreateIndex
+CREATE INDEX "Comments_userId_idx" ON "Comments"("userId");
+
+-- CreateIndex
+CREATE INDEX "Comments_deletedAt_idx" ON "Comments"("deletedAt");
+
+-- CreateIndex
+CREATE INDEX "Post_group_idx" ON "Post"("group");
+
+-- CreateIndex
+CREATE INDEX "Post_deletedAt_idx" ON "Post"("deletedAt");
+
+-- CreateIndex
+CREATE INDEX "Post_publishDate_idx" ON "Post"("publishDate");
+
+-- CreateIndex
+CREATE INDEX "Post_state_idx" ON "Post"("state");
+
+-- CreateIndex
+CREATE INDEX "Post_organizationId_idx" ON "Post"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Post_parentPostId_idx" ON "Post"("parentPostId");
+
+-- CreateIndex
+CREATE INDEX "Post_submittedForOrderId_idx" ON "Post"("submittedForOrderId");
+
+-- CreateIndex
+CREATE INDEX "Post_approvedSubmitForOrder_idx" ON "Post"("approvedSubmitForOrder");
+
+-- CreateIndex
+CREATE INDEX "Post_lastMessageId_idx" ON "Post"("lastMessageId");
+
+-- CreateIndex
+CREATE INDEX "Post_createdAt_idx" ON "Post"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "Post_updatedAt_idx" ON "Post"("updatedAt");
+
+-- CreateIndex
+CREATE INDEX "Post_releaseURL_idx" ON "Post"("releaseURL");
+
+-- CreateIndex
+CREATE INDEX "Post_integrationId_idx" ON "Post"("integrationId");
+
+-- CreateIndex
+CREATE INDEX "Notifications_createdAt_idx" ON "Notifications"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "Notifications_organizationId_idx" ON "Notifications"("organizationId");
+
+-- CreateIndex
+CREATE INDEX "Notifications_deletedAt_idx" ON "Notifications"("deletedAt");
+
+-- CreateIndex
+CREATE INDEX "MessagesGroup_createdAt_idx" ON "MessagesGroup"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "MessagesGroup_updatedAt_idx" ON "MessagesGroup"("updatedAt");
+
+-- CreateIndex
+CREATE INDEX "MessagesGroup_buyerOrganizationId_idx" ON "MessagesGroup"("buyerOrganizationId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "MessagesGroup_buyerId_sellerId_key" ON "MessagesGroup"("buyerId", "sellerId");
+
+-- CreateIndex
+CREATE INDEX "Orders_buyerId_idx" ON "Orders"("buyerId");
+
+-- CreateIndex
+CREATE INDEX "Orders_sellerId_idx" ON "Orders"("sellerId");
+
+-- CreateIndex
+CREATE INDEX "Orders_updatedAt_idx" ON "Orders"("updatedAt");
+
+-- CreateIndex
+CREATE INDEX "Orders_createdAt_idx" ON "Orders"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "Orders_messageGroupId_idx" ON "Orders"("messageGroupId");
+
+-- CreateIndex
+CREATE INDEX "OrderItems_orderId_idx" ON "OrderItems"("orderId");
+
+-- CreateIndex
+CREATE INDEX "OrderItems_integrationId_idx" ON "OrderItems"("integrationId");
+
+-- CreateIndex
+CREATE INDEX "Messages_groupId_idx" ON "Messages"("groupId");
+
+-- CreateIndex
+CREATE INDEX "Messages_createdAt_idx" ON "Messages"("createdAt");
+
+-- CreateIndex
+CREATE INDEX "Messages_deletedAt_idx" ON "Messages"("deletedAt");
+
+-- CreateIndex
+CREATE INDEX "Plugs_organizationId_idx" ON "Plugs"("organizationId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Plugs_plugFunction_integrationId_key" ON "Plugs"("plugFunction", "integrationId");
+
+-- CreateIndex
+CREATE UNIQUE INDEX "ExisingPlugData_integrationId_methodName_value_key" ON "ExisingPlugData"("integrationId", "methodName", "value");
+
+-- AddForeignKey
+ALTER TABLE "User" ADD CONSTRAINT "User_pictureId_fkey" FOREIGN KEY ("pictureId") REFERENCES "Media"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "UsedCodes" ADD CONSTRAINT "UsedCodes_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "UserOrganization" ADD CONSTRAINT "UserOrganization_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "UserOrganization" ADD CONSTRAINT "UserOrganization_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "GitHub" ADD CONSTRAINT "GitHub_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "ItemUser" ADD CONSTRAINT "ItemUser_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Media" ADD CONSTRAINT "Media_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SocialMediaAgency" ADD CONSTRAINT "SocialMediaAgency_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SocialMediaAgency" ADD CONSTRAINT "SocialMediaAgency_logoId_fkey" FOREIGN KEY ("logoId") REFERENCES "Media"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "SocialMediaAgencyNiche" ADD CONSTRAINT "SocialMediaAgencyNiche_agencyId_fkey" FOREIGN KEY ("agencyId") REFERENCES "SocialMediaAgency"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Credits" ADD CONSTRAINT "Credits_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Subscription" ADD CONSTRAINT "Subscription_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Customer" ADD CONSTRAINT "Customer_orgId_fkey" FOREIGN KEY ("orgId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Integration" ADD CONSTRAINT "Integration_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Integration" ADD CONSTRAINT "Integration_customerId_fkey" FOREIGN KEY ("customerId") REFERENCES "Customer"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Comments" ADD CONSTRAINT "Comments_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Comments" ADD CONSTRAINT "Comments_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Comments" ADD CONSTRAINT "Comments_parentCommentId_fkey" FOREIGN KEY ("parentCommentId") REFERENCES "Comments"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_parentPostId_fkey" FOREIGN KEY ("parentPostId") REFERENCES "Post"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_submittedForOrderId_fkey" FOREIGN KEY ("submittedForOrderId") REFERENCES "Orders"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_submittedForOrganizationId_fkey" FOREIGN KEY ("submittedForOrganizationId") REFERENCES "Organization"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Post" ADD CONSTRAINT "Post_lastMessageId_fkey" FOREIGN KEY ("lastMessageId") REFERENCES "Messages"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Notifications" ADD CONSTRAINT "Notifications_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "MessagesGroup" ADD CONSTRAINT "MessagesGroup_buyerOrganizationId_fkey" FOREIGN KEY ("buyerOrganizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "MessagesGroup" ADD CONSTRAINT "MessagesGroup_buyerId_fkey" FOREIGN KEY ("buyerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "MessagesGroup" ADD CONSTRAINT "MessagesGroup_sellerId_fkey" FOREIGN KEY ("sellerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PayoutProblems" ADD CONSTRAINT "PayoutProblems_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Orders"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PayoutProblems" ADD CONSTRAINT "PayoutProblems_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "PayoutProblems" ADD CONSTRAINT "PayoutProblems_postId_fkey" FOREIGN KEY ("postId") REFERENCES "Post"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Orders" ADD CONSTRAINT "Orders_buyerId_fkey" FOREIGN KEY ("buyerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Orders" ADD CONSTRAINT "Orders_sellerId_fkey" FOREIGN KEY ("sellerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Orders" ADD CONSTRAINT "Orders_messageGroupId_fkey" FOREIGN KEY ("messageGroupId") REFERENCES "MessagesGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "OrderItems" ADD CONSTRAINT "OrderItems_orderId_fkey" FOREIGN KEY ("orderId") REFERENCES "Orders"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "OrderItems" ADD CONSTRAINT "OrderItems_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Messages" ADD CONSTRAINT "Messages_groupId_fkey" FOREIGN KEY ("groupId") REFERENCES "MessagesGroup"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Plugs" ADD CONSTRAINT "Plugs_organizationId_fkey" FOREIGN KEY ("organizationId") REFERENCES "Organization"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Plugs" ADD CONSTRAINT "Plugs_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "ExisingPlugData" ADD CONSTRAINT "ExisingPlugData_integrationId_fkey" FOREIGN KEY ("integrationId") REFERENCES "Integration"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/libraries/nestjs-libraries/src/database/prisma/migrations/migration_lock.toml b/libraries/nestjs-libraries/src/database/prisma/migrations/migration_lock.toml
new file mode 100644
index 00000000..fbffa92c
--- /dev/null
+++ b/libraries/nestjs-libraries/src/database/prisma/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
+# Please do not edit this file manually
+# It should be added in your version-control system (i.e. Git)
+provider = "postgresql"
\ No newline at end of file
diff --git a/libraries/nestjs-libraries/src/database/prisma/schema.prisma b/libraries/nestjs-libraries/src/database/prisma/schema.prisma
index 3edef3ce..77829622 100644
--- a/libraries/nestjs-libraries/src/database/prisma/schema.prisma
+++ b/libraries/nestjs-libraries/src/database/prisma/schema.prisma
@@ -42,6 +42,7 @@ model User {
lastName String?
isSuperAdmin Boolean @default(false)
bio String?
+ openAIAPIKey String?
audience Int @default(0)
pictureId String?
picture Media? @relation(fields: [pictureId], references: [id])
@@ -529,4 +530,4 @@ enum APPROVED_SUBMIT_FOR_ORDER {
NO
WAITING_CONFIRMATION
YES
-}
\ No newline at end of file
+}
diff --git a/libraries/nestjs-libraries/src/database/prisma/users/users.repository.ts b/libraries/nestjs-libraries/src/database/prisma/users/users.repository.ts
index 2df55338..811716b5 100644
--- a/libraries/nestjs-libraries/src/database/prisma/users/users.repository.ts
+++ b/libraries/nestjs-libraries/src/database/prisma/users/users.repository.ts
@@ -128,6 +128,7 @@ export class UsersRepository {
id: true,
name: true,
bio: true,
+ openAIAPIKey: true,
picture: {
select: {
id: true,
@@ -148,6 +149,7 @@ export class UsersRepository {
data: {
name: body.fullname,
bio: body.bio,
+ openAIAPIKey: body.openAIAPIKey,
picture: body.picture
? {
connect: {
diff --git a/libraries/nestjs-libraries/src/dtos/users/user.details.dto.ts b/libraries/nestjs-libraries/src/dtos/users/user.details.dto.ts
index c218ce3e..e0ba8c61 100644
--- a/libraries/nestjs-libraries/src/dtos/users/user.details.dto.ts
+++ b/libraries/nestjs-libraries/src/dtos/users/user.details.dto.ts
@@ -1,5 +1,10 @@
import { MediaDto } from '@gitroom/nestjs-libraries/dtos/media/media.dto';
-import { IsOptional, IsString, MinLength, ValidateNested } from 'class-validator';
+import {
+ IsOptional,
+ IsString,
+ MinLength,
+ ValidateNested,
+} from 'class-validator';
export class UserDetailDto {
@IsString()
@@ -10,7 +15,12 @@ export class UserDetailDto {
@IsOptional()
bio: string;
+ @IsString()
+ @IsOptional()
+ openAIAPIKey: string;
+
@IsOptional()
@ValidateNested()
picture: MediaDto;
-}
\ No newline at end of file
+}
+
diff --git a/libraries/nestjs-libraries/src/integrations/integration.manager.ts b/libraries/nestjs-libraries/src/integrations/integration.manager.ts
index 09756576..91499b59 100644
--- a/libraries/nestjs-libraries/src/integrations/integration.manager.ts
+++ b/libraries/nestjs-libraries/src/integrations/integration.manager.ts
@@ -21,10 +21,11 @@ import { DiscordProvider } from '@gitroom/nestjs-libraries/integrations/social/d
import { SlackProvider } from '@gitroom/nestjs-libraries/integrations/social/slack.provider';
import { MastodonProvider } from '@gitroom/nestjs-libraries/integrations/social/mastodon.provider';
import { BlueskyProvider } from '@gitroom/nestjs-libraries/integrations/social/bluesky.provider';
+import { XSelfProvider } from '@gitroom/nestjs-libraries/integrations/social/xself.provider';
// import { MastodonCustomProvider } from '@gitroom/nestjs-libraries/integrations/social/mastodon.custom.provider';
const socialIntegrationList: SocialProvider[] = [
- new XProvider(),
+ process.env.ENABLE_X_SELF === 'true' ? new XSelfProvider() : new XProvider(),
new LinkedinProvider(),
new LinkedinPageProvider(),
new RedditProvider(),
diff --git a/libraries/nestjs-libraries/src/integrations/social/xself.provider.ts b/libraries/nestjs-libraries/src/integrations/social/xself.provider.ts
new file mode 100644
index 00000000..7298c1ab
--- /dev/null
+++ b/libraries/nestjs-libraries/src/integrations/social/xself.provider.ts
@@ -0,0 +1,304 @@
+import { TwitterApi } from 'twitter-api-v2';
+import {
+ AuthTokenDetails,
+ PostDetails,
+ PostResponse,
+ SocialProvider,
+} from '@gitroom/nestjs-libraries/integrations/social/social.integrations.interface';
+import { lookup } from 'mime-types';
+import sharp from 'sharp';
+import { readOrFetch } from '@gitroom/helpers/utils/read.or.fetch';
+import removeMd from 'remove-markdown';
+import { SocialAbstract } from '@gitroom/nestjs-libraries/integrations/social.abstract';
+import { Plug } from '@gitroom/helpers/decorators/plug.decorator';
+import { Integration } from '@prisma/client';
+import { timer } from '@gitroom/helpers/utils/timer';
+import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
+import { text } from 'stream/consumers';
+
+export class XSelfProvider extends SocialAbstract implements SocialProvider {
+ identifier = 'xself';
+ name = 'X Self API Token';
+ isBetweenSteps = false;
+ scopes = [];
+ async customFields() {
+ return [
+ {
+ key: 'apiKey',
+ label: 'API Key',
+ defaultValue: '',
+ validation: `/^.{3,}$/`,
+ type: 'text' as const,
+ },
+ {
+ key: 'apiSecretKey',
+ label: 'API Secret Key',
+ validation: `/^.{3,}$/`,
+ type: 'text' as const,
+ },
+ {
+ key: 'accessToken',
+ label: 'Access Token',
+ validation: `/^.{3,}$/`,
+ type: 'text' as const,
+ },
+ {
+ key: 'accessTokenSecret',
+ label: 'Access Token Secret',
+ validation: `/^.{3,}$/`,
+ type: 'text' as const,
+ },
+ ];
+ }
+
+ @Plug({
+ identifier: 'xself-autoRepostPost',
+ title: 'Auto Repost Posts',
+ description:
+ 'When a post reached a certain number of likes, repost it to increase engagement (1 week old posts)',
+ runEveryMilliseconds: 21600000,
+ totalRuns: 3,
+ fields: [
+ {
+ name: 'likesAmount',
+ type: 'number',
+ placeholder: 'Amount of likes',
+ description: 'The amount of likes to trigger the repost',
+ validation: /^\d+$/,
+ },
+ ],
+ })
+ async autoRepostPost(
+ integration: Integration,
+ id: string,
+ fields: { likesAmount: string }
+ ) {
+ const [
+ apiKeySplit,
+ apiSecretKeySplit,
+ accessTokenSplit,
+ accessTokenSecretSplit,
+ ] = integration.token.split(':');
+ const client = new TwitterApi({
+ appKey: apiKeySplit,
+ appSecret: apiSecretKeySplit,
+ accessToken: accessTokenSplit,
+ accessSecret: accessTokenSecretSplit,
+ });
+ if (
+ (await client.v2.tweetLikedBy(id)).meta.result_count >=
+ +fields.likesAmount
+ ) {
+ await timer(2000);
+ await client.v2.retweet(integration.internalId, id);
+ return true;
+ }
+
+ return false;
+ }
+
+ @Plug({
+ identifier: 'xself-autoPlugPost',
+ title: 'Auto plug post',
+ description:
+ 'When a post reached a certain number of likes, add another post to it so you followers get a notification about your promotion',
+ runEveryMilliseconds: 21600000,
+ totalRuns: 3,
+ fields: [
+ {
+ name: 'likesAmount',
+ type: 'number',
+ placeholder: 'Amount of likes',
+ description: 'The amount of likes to trigger the repost',
+ validation: /^\d+$/,
+ },
+ {
+ name: 'post',
+ type: 'richtext',
+ placeholder: 'Post to plug',
+ description: 'Message content to plug',
+ validation: /^[\s\S]{3,}$/g,
+ },
+ ],
+ })
+ async autoPlugPost(
+ integration: Integration,
+ id: string,
+ fields: { likesAmount: string; post: string }
+ ) {
+ const [
+ apiKeySplit,
+ apiSecretKeySplit,
+ accessTokenSplit,
+ accessTokenSecretSplit,
+ ] = integration.token.split(':');
+ const client = new TwitterApi({
+ appKey: apiKeySplit,
+ appSecret: apiSecretKeySplit,
+ accessToken: accessTokenSplit,
+ accessSecret: accessTokenSecretSplit,
+ });
+
+ if (
+ (await client.v2.tweetLikedBy(id)).meta.result_count >=
+ +fields.likesAmount
+ ) {
+ await timer(2000);
+
+ await client.v2.tweet({
+ text: removeMd(fields.post.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢')).replace(
+ '𝔫𝔢𝔴𝔩𝔦𝔫𝔢',
+ '\n'
+ ),
+ reply: { in_reply_to_tweet_id: id },
+ });
+ return true;
+ }
+
+ return false;
+ }
+
+ async refreshToken(refreshToken: string): Promise
{
+ return {
+ refreshToken: '',
+ expiresIn: 0,
+ accessToken: '',
+ id: '',
+ name: '',
+ picture: '',
+ username: '',
+ };
+ }
+
+ async generateAuthUrl() {
+ const state = makeId(6);
+ return {
+ url: '',
+ codeVerifier: makeId(10),
+ state,
+ };
+ }
+
+ async authenticate(params: { code: string; codeVerifier: string }) {
+ const body = JSON.parse(Buffer.from(params.code, 'base64').toString());
+
+ const { code, codeVerifier } = params;
+ const [oauth_token, oauth_token_secret] = codeVerifier.split(':');
+
+ const startingClient = new TwitterApi({
+ appKey: body.apiKey,
+ appSecret: body.apiSecretKey,
+ accessToken: body.accessToken,
+ accessSecret: body.accessTokenSecret,
+ });
+
+ const { id, name, profile_image_url_https, screen_name } =
+ await startingClient.currentUser(true);
+
+ return {
+ id: String(id),
+ accessToken:
+ body.apiKey +
+ ':' +
+ body.apiSecretKey +
+ ':' +
+ body.accessToken +
+ ':' +
+ body.accessTokenSecret,
+
+ name,
+ refreshToken: '',
+ expiresIn: 999999999,
+ picture: profile_image_url_https,
+ username: screen_name,
+ };
+ }
+
+ async post(
+ id: string,
+ accessToken: string,
+ postDetails: PostDetails[]
+ ): Promise {
+ const [
+ apiKeySplit,
+ apiSecretKeySplit,
+ accessTokenSplit,
+ accessTokenSecretSplit,
+ ] = accessToken.split(':');
+ const client = new TwitterApi({
+ appKey: apiKeySplit,
+ appSecret: apiSecretKeySplit,
+ accessToken: accessTokenSplit,
+ accessSecret: accessTokenSecretSplit,
+ });
+
+ const { name, profile_image_url_https, screen_name } =
+ await client.currentUser(true);
+
+ // upload everything before, you don't want it to fail between the posts
+ const uploadAll = (
+ await Promise.all(
+ postDetails.flatMap((p) =>
+ p?.media?.flatMap(async (m) => {
+ return {
+ id: await client.v1.uploadMedia(
+ m.url.indexOf('mp4') > -1
+ ? Buffer.from(await readOrFetch(m.url))
+ : await sharp(await readOrFetch(m.url), {
+ animated: lookup(m.url) === 'image/gif',
+ })
+ .resize({
+ width: 1000,
+ })
+ .gif()
+ .toBuffer(),
+ {
+ mimeType: lookup(m.url) || '',
+ }
+ ),
+ postId: p.id,
+ };
+ })
+ )
+ )
+ ).reduce((acc, val) => {
+ if (!val?.id) {
+ return acc;
+ }
+
+ acc[val.postId] = acc[val.postId] || [];
+ acc[val.postId].push(val.id);
+
+ return acc;
+ }, {} as Record);
+
+ const ids: Array<{ postId: string; id: string; releaseURL: string }> = [];
+ for (const post of postDetails) {
+ const media_ids = (uploadAll[post.id] || []).filter((f) => f);
+ // @ts-ignore
+ const { data }: { data: { id: string } } = await client.v2.tweet({
+ text: removeMd(post.message.replace('\n', '𝔫𝔢𝔴𝔩𝔦𝔫𝔢')).replace(
+ '𝔫𝔢𝔴𝔩𝔦𝔫𝔢',
+ '\n'
+ ),
+ ...(media_ids.length ? { media: { media_ids } } : {}),
+ ...(ids.length
+ ? { reply: { in_reply_to_tweet_id: ids[ids.length - 1].postId } }
+ : {}),
+ });
+
+ console.log('GGG DATA', data);
+
+ ids.push({
+ postId: data.id,
+ id: post.id,
+ releaseURL: `https://twitter.com/${screen_name}/status/${data.id}`,
+ });
+ }
+
+ return ids.map((p) => ({
+ ...p,
+ status: 'posted',
+ }));
+ }
+}
diff --git a/libraries/nestjs-libraries/src/upload/cloudflare.storage.ts b/libraries/nestjs-libraries/src/upload/cloudflare.storage.ts
index 6bf12ef1..c349d8b4 100644
--- a/libraries/nestjs-libraries/src/upload/cloudflare.storage.ts
+++ b/libraries/nestjs-libraries/src/upload/cloudflare.storage.ts
@@ -3,7 +3,7 @@ import 'multer';
import { makeId } from '@gitroom/nestjs-libraries/services/make.is';
import mime from 'mime-types';
// @ts-ignore
-import {getExtension} from 'mime';
+import { getExtension } from 'mime';
import { IUploadProvider } from './upload.interface';
import axios from 'axios';
@@ -30,7 +30,9 @@ class CloudflareStorage implements IUploadProvider {
async uploadSimple(path: string) {
const loadImage = await axios.get(path, { responseType: 'arraybuffer' });
- const contentType = loadImage?.headers?.['content-type'] || loadImage?.headers?.['Content-Type'];
+ const contentType =
+ loadImage?.headers?.['content-type'] ||
+ loadImage?.headers?.['Content-Type'];
const extension = getExtension(contentType)!;
const id = makeId(10);
@@ -42,7 +44,11 @@ class CloudflareStorage implements IUploadProvider {
};
const command = new PutObjectCommand({ ...params });
- await this._client.send(command);
+ try {
+ await this._client.send(command);
+ } catch (e) {
+ console.log(e);
+ }
return `${this._uploadUrl}/${id}.${extension}`;
}
diff --git a/libraries/react-shared-libraries/src/helpers/variable.context.tsx b/libraries/react-shared-libraries/src/helpers/variable.context.tsx
index cac54ca0..9886f163 100644
--- a/libraries/react-shared-libraries/src/helpers/variable.context.tsx
+++ b/libraries/react-shared-libraries/src/helpers/variable.context.tsx
@@ -5,9 +5,10 @@ import { createContext, FC, ReactNode, useContext, useEffect } from 'react';
interface VariableContextInterface {
billingEnabled: boolean;
isGeneral: boolean;
+ enabledOpenaiSelf: boolean;
frontEndUrl: string;
plontoKey: string;
- storageProvider: 'local' | 'cloudflare',
+ storageProvider: 'local' | 'cloudflare';
backendUrl: string;
discordUrl: string;
uploadDirectory: string;
@@ -16,6 +17,7 @@ interface VariableContextInterface {
const VariableContext = createContext({
billingEnabled: false,
isGeneral: true,
+ enabledOpenaiSelf: false,
frontEndUrl: '',
storageProvider: 'local',
plontoKey: '',
@@ -44,9 +46,9 @@ export const VariableContextComponent: FC<
export const useVariables = () => {
return useContext(VariableContext);
-}
+};
export const loadVars = () => {
// @ts-ignore
return window.vars as VariableContextInterface;
-}
+};