From 95d2fee63d88777177bf84942ae3bdbd630313f2 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Tue, 29 Jul 2025 13:08:01 -0700 Subject: [PATCH] Paste.gg: fully removed, the website seems up no more --- README.md | 2 +- src/modules/trade/ExportChats.tsx | 5 - src/modules/trade/publish/PublishDetails.tsx | 65 ----------- src/modules/trade/publish/PublishExport.tsx | 112 ------------------- src/modules/trade/server/pastegg.ts | 106 ------------------ src/modules/trade/server/trade.router.ts | 27 ----- 6 files changed, 1 insertion(+), 316 deletions(-) delete mode 100644 src/modules/trade/publish/PublishDetails.tsx delete mode 100644 src/modules/trade/publish/PublishExport.tsx delete mode 100644 src/modules/trade/server/pastegg.ts diff --git a/README.md b/README.md index 2d01836a4..0a24c0086 100644 --- a/README.md +++ b/README.md @@ -190,7 +190,7 @@ Add extra functionality with these integrations: | Web Browse | [Browserless](https://www.browserless.io/) · [Puppeteer](https://pptr.dev/)-based | | Web Search | [Google CSE](https://programmablesearchengine.google.com/) | | Code Editors | [CodePen](https://codepen.io/pen/) · [StackBlitz](https://stackblitz.com/) · [JSFiddle](https://jsfiddle.net/) | -| Sharing | [Paste.gg](https://paste.gg/) (Paste chats) | + | Tracking | [Helicone](https://www.helicone.ai) (LLM Observability) | [//]: # (- [x] **Flow-state UX** for uncompromised productivity) diff --git a/src/modules/trade/ExportChats.tsx b/src/modules/trade/ExportChats.tsx index 2d98afcb5..8e31576ee 100644 --- a/src/modules/trade/ExportChats.tsx +++ b/src/modules/trade/ExportChats.tsx @@ -13,7 +13,6 @@ import { getConversation } from '~/common/stores/chat/store-chats'; import { ChatLinkExport } from './link/ChatLinkExport'; import { FlashBackup } from './BackupRestore'; -import { PublishExport } from './publish/PublishExport'; import { downloadAllJsonV1B, downloadSingleChat } from './trade.client'; @@ -114,10 +113,6 @@ export function ExportChats(props: { config: ExportConfig, onClose: () => void } /> )} - {/* void, response: PublishedSchema, open: boolean }) { - if (!props.response?.url) - return null; - - const { url, deletionKey, expires } = props.response; - - return ( - - - - - Your conversation is live! - - - - - - This is your link (opens in a new window) - - - - {url} - - - - - - - Deletion key - - - - IMPORTANT - Keep this key safe! You will need it if you decide to delete the paste, and it will not appear again once you close this dialog. - - - - - {expires?.length >= 10 && ( - - The conversation will be deleted on {new Date(expires).toLocaleString()}. - - )} - - - - - - - ); -} \ No newline at end of file diff --git a/src/modules/trade/publish/PublishExport.tsx b/src/modules/trade/publish/PublishExport.tsx deleted file mode 100644 index ff3ec3dfc..000000000 --- a/src/modules/trade/publish/PublishExport.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import * as React from 'react'; - -import { Button } from '@mui/joy'; -import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'; - -import { getChatShowSystemMessages } from '../../../apps/chat/store-app-chat'; - -import type { DConversationId } from '~/common/stores/chat/chat.conversation'; -import { Brand } from '~/common/app.config'; -import { ConfirmationModal } from '~/common/components/modals/ConfirmationModal'; -import { Link } from '~/common/components/Link'; -import { apiAsyncNode } from '~/common/util/trpc.client'; -import { getConversation } from '~/common/stores/chat/store-chats'; -import { isBrowser } from '~/common/util/pwaUtils'; - -import type { PublishedSchema } from '../server/pastegg'; -import { PublishDetails } from './PublishDetails'; -import { conversationToMarkdown } from '../trade.client'; - - -/// Returns a pretty link to the current page, for promo -function linkToOrigin() { - let origin = isBrowser ? window.location.href : ''; - if (!origin || origin.includes('//localhost')) - origin = Brand.URIs.OpenRepo; - origin = origin.replace('https://', ''); - if (origin.endsWith('/')) - origin = origin.slice(0, -1); - return origin; -} - - -export function PublishExport(props: { - conversationId: DConversationId | null; - onClose: () => void; -}) { - - // local state - const [publishConversationId, setPublishConversationId] = React.useState(null); - const [publishUploading, setPublishUploading] = React.useState(false); - const [publishResponse, setPublishResponse] = React.useState(null); - - - const handlePublishConversation = () => setPublishConversationId(props.conversationId); - - const handlePublishConfirmed = async () => { - if (!publishConversationId) return; - - const conversation = getConversation(publishConversationId); - setPublishConversationId(null); - if (!conversation) return; - - setPublishUploading(true); - const showSystemMessages = getChatShowSystemMessages(); - const markdownContent = conversationToMarkdown(conversation, !showSystemMessages, false); - try { - const paste = await apiAsyncNode.trade.publishTo.mutate({ - to: 'paste.gg', - title: '🤖💬 Chat Conversation', - fileContent: markdownContent, - fileName: 'my-chat.md', - origin: linkToOrigin(), - }); - setPublishResponse(paste); - } catch (error: any) { - alert(`Failed to publish conversation: ${error?.message ?? error?.toString() ?? 'unknown error'}`); - setPublishResponse(null); - } - setPublishUploading(false); - }; - - const handlePublishResponseClosed = () => { - setPublishResponse(null); - props.onClose(); - }; - - - const hasConversation = !!props.conversationId; - - - return <> - - - - {/* [publish] confirmation */} - {publishConversationId && ( - setPublishConversationId(null)} onPositive={handlePublishConfirmed} - confirmationText={<> - Share your conversation anonymously on paste.gg? - It will be unlisted and available to share and read for 30 days. Keep in mind, deletion may not be possible. - Do you wish to continue? - } positiveActionText={'Understood, Upload to Paste.gg'} - /> - )} - - {/* [publish] response */} - {!!publishResponse && ( - - )} - - ; -} \ No newline at end of file diff --git a/src/modules/trade/server/pastegg.ts b/src/modules/trade/server/pastegg.ts deleted file mode 100644 index dfd395413..000000000 --- a/src/modules/trade/server/pastegg.ts +++ /dev/null @@ -1,106 +0,0 @@ -import * as z from 'zod/v4'; - -import { fetchJsonOrTRPCThrow } from '~/server/trpc/trpc.router.fetchers'; - - -export const publishToInputSchema = z.object({ - to: z.enum(['paste.gg']), - title: z.string(), - fileContent: z.string(), - fileName: z.string(), - origin: z.string(), -}); - -export const publishToOutputSchema = z.object({ - url: z.string(), - expires: z.string(), - deletionKey: z.string(), - created: z.string(), -}); - -export type PublishedSchema = z.infer; - -/** - * Post a paste to paste.gg - * [called by the API] - * - API description: https://github.com/ascclemens/paste/blob/master/api.md - * - * @param title Title of the paste - * @param fileName File with extension, e.g. 'conversation.md' - * @param fileContent Textual content (e.g. markdown text) - * @param origin the URL of the page that generated the paste - * @param expireDays Number of days after which the paste will expire (0 = never expires, default = 30) - */ -export async function postToPasteGGOrThrow(title: string, fileName: string, fileContent: string, origin: string, expireDays: number = 30): Promise { - - // Default: expire in 30 days - let expires = null; - if (expireDays && expireDays >= 1) { - const expirationDate = new Date(); - expirationDate.setDate(expirationDate.getDate() + expireDays); - expires = expirationDate.toISOString(); - } - - const pasteData: PasteGGWire.PasteRequest = { - name: title, - description: `Generated by ${origin} 🚀`, - visibility: 'unlisted', - ...(expires && { expires }), - files: [{ - name: fileName, - content: { - format: 'text', - value: fileContent, - }, - }], - }; - - return await fetchJsonOrTRPCThrow({ - url: 'https://api.paste.gg/v1/pastes', - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: pasteData, - name: 'PasteGG', - }); -} - - -namespace PasteGGWire { - - export interface PasteRequest { - name?: string; - description?: string; - visibility?: 'public' | 'unlisted' | 'private'; - expires?: string; - files: PasteFile[]; - } - - interface PasteFile { - name?: string; - content: { - format: 'text' | 'base64' | 'gzip' | 'xz'; - highlight_language?: string | null; - value: string; - }; - } - - export type PasteResponse = { - status: 'success' - result: PasteRequest & { - id: string; - created_at: string; - updated_at: string; - files: { - id: string; - name: string; - highlight_language?: string | null; - }[]; - deletion_key?: string; - }; - } | { - status: 'error'; - error: string; - message?: string; - } - -} \ No newline at end of file diff --git a/src/modules/trade/server/trade.router.ts b/src/modules/trade/server/trade.router.ts index 783ae61e6..5a0d86ad2 100644 --- a/src/modules/trade/server/trade.router.ts +++ b/src/modules/trade/server/trade.router.ts @@ -5,7 +5,6 @@ import { createTRPCRouter, publicProcedure } from '~/server/trpc/trpc.server'; import { fetchTextOrTRPCThrow } from '~/server/trpc/trpc.router.fetchers'; import { chatGptParseConversation, chatGptSharedChatSchema } from './chatgpt'; -import { postToPasteGGOrThrow, publishToInputSchema, publishToOutputSchema } from './pastegg'; import { storageGetProcedure, storageMarkAsDeletedProcedure, storagePutProcedure, storageUpdateDeletionKeyProcedure } from './link'; @@ -74,31 +73,5 @@ export const tradeRouter = createTRPCRouter({ */ storageUpdateDeletionKey: storageUpdateDeletionKeyProcedure, - /** - * Publish a text file (with title, content, name) to a sharing service - * For now only 'paste.gg' is supported - */ - publishTo: publicProcedure - .input(publishToInputSchema) - .output(publishToOutputSchema) - .mutation(async ({ input: { to, title, fileContent, fileName, origin } }) => { - if (to !== 'paste.gg' || !title || !fileContent || !fileName) - throw new Error('Invalid options'); - - const paste = await postToPasteGGOrThrow(title, fileName, fileContent, origin); - if (paste?.status !== 'success') - throw new TRPCError({ - code: 'BAD_REQUEST', - message: `${paste?.error || 'Unknown error'}. ${paste?.message || 'Unknown cause'}`.trim(), - }); - - const result = paste.result; - return { - url: `https://paste.gg/${result.id}`, - expires: result.expires || 'never', - deletionKey: result.deletion_key || 'none', - created: result.created_at, - }; - }), }); \ No newline at end of file