Skip to content

Contribution: Custom Action for Article Summarization via ChatGPT #218

@darkneoss

Description

@darkneoss

Hi reader-view team & community,

First off, thanks for the great extension!

I'm opening this issue just to share a custom action I created, not to report a bug or request a feature.

Leveraging the custom actions feature, I built one that uses the OpenAI API (ChatGPT) to summarize the current article.

I know there might be similar solutions, but I thought it would be a neat integration to share. I'm providing the code below as a contribution for anyone interested in using or adapting it.

Note: This action requires an OpenAI API Key. It is required to add it in the section that says "APIKEY" and not to share it with anyone.

https://i.imgur.com/OC3H2ZE.png

[
  {
    "code": "(function() {\n  const contenido = document.body.innerText.trim();\n  if (!contenido) { alert('No se encontró contenido para resumir.'); return; }\n\n  // Crear un modal personalizado con estilos\n  const modal = document.createElement('div');\n  modal.style.cssText = `\n    position: fixed;\n    top: 30%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    width: 700px;\n    max-width: 90%;\n    max-height: 80%;\n    background: white;\n    border-radius: 12px;\n    box-shadow: 0 10px 25px rgba(0,0,0,0.1);\n    overflow: hidden;\n    z-index: 1000;\n    font-family: Arial, sans-serif;\n  `;\n\n  // Encabezado del modal\n  const header = document.createElement('div');\n  header.style.cssText = `\n    background: #4a90e2;\n    color: white;\n    padding: 15px;\n    display: flex;\n    justify-content: space-between;\n    align-items: center;\n  `;\n\n  const title = document.createElement('h2');\n  title.textContent = 'Resumen del Artículo';\n  title.style.margin = '0';\n\n  const closeBtn = document.createElement('button');\n  closeBtn.textContent = '×';\n  closeBtn.style.cssText = `\n    background: none;\n    border: none;\n    color: white;\n    font-size: 24px;\n    cursor: pointer;\n  `;\n\n  header.appendChild(title);\n  header.appendChild(closeBtn);\n\n  // Contenido del resumen\n  const content = document.createElement('div');\n  content.style.cssText = `\n    padding: 20px;\n    max-height: 500px;\n    overflow-y: auto;\n    line-height: 1.6;\n    color: #333;\n  `;\n\n  // Botón de copiar\n  const copyBtn = document.createElement('button');\n  copyBtn.textContent = 'Copiar Resumen';\n  copyBtn.style.cssText = `\n    position: absolute;\n    bottom: 15px;\n    right: 15px;\n    background: #4CAF50;\n    color: white;\n    border: none;\n    padding: 10px 15px;\n    border-radius: 5px;\n    cursor: pointer;\n  `;\n\n  modal.appendChild(header);\n  modal.appendChild(content);\n  modal.appendChild(copyBtn);\n  document.body.appendChild(modal);\n\n  const prompt = 'Resume el siguiente texto: ' + contenido;\n\n  // Indicador de carga\n  content.innerHTML = `\n    <div style=\"text-align: center; padding: 20px;\">\n      <div style=\"\n        width: 50px;\n        height: 50px;\n        border: 5px solid #f3f3f3;\n        border-top: 5px solid #4a90e2;\n        border-radius: 50%;\n        animation: spin 1s linear infinite;\n      \"></div>\n      <p>Generando resumen...</p>\n    </div>\n    <style>\n      @keyframes spin {\n        0% { transform: rotate(0deg); }\n        100% { transform: rotate(360deg); }\n      }\n    </style>\n  `;\n\n  fetch('https://api.openai.com/v1/chat/completions', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Authorization': 'Bearer APIKEY'\n    },\n    body: JSON.stringify({\n      model: 'gpt-4.1-nano',\n      messages: [\n        { 'role': 'system', 'content': 'Eres un asistente que resume textos en bullets con emojis de forma concisa y clara.' },\n        { 'role': 'user', 'content': prompt }\n      ],\n      max_tokens: 900,\n      temperature: 0.7\n    })\n  })\n  .then(response => response.json())\n  .then(data => {\n    if (data.choices && data.choices.length > 0) {\n      const resumen = data.choices[0].message.content.trim();\n      content.innerHTML = `\n        <h3 style=\"color: #4a90e2; border-bottom: 2px solid #4a90e2; padding-bottom: 10px;\">\n          Puntos Principales\n        </h3>\n        <p style=\"white-space: pre-wrap;\">${resumen}</p>\n      `;\n    } else {\n      content.innerHTML = '<p style=\"color: red;\">No se obtuvo respuesta adecuada de la API.</p>';\n    }\n  })\n  .catch(err => {\n    console.error('Error al resumir:', err);\n    content.innerHTML = `<p style=\"color: red;\">Error al resumir: ${err.message}</p>`;\n  });\n\n  // Eventos\n  closeBtn.addEventListener('click', () => document.body.removeChild(modal));\n  copyBtn.addEventListener('click', () => {\n    navigator.clipboard.writeText(content.textContent).then(() => {\n      copyBtn.textContent = '¡Copiado!';\n      copyBtn.style.background = '#45a049';\n      setTimeout(() => {\n        copyBtn.textContent = 'Copiar Resumen';\n        copyBtn.style.background = '#4CAF50';\n      }, 2000);\n    });\n  });\n})();",
    "shortcut": "Ctrl/Command + Shift + KeyZ",
    "title": "Resumir ChatGPT"
  }
]

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions