• এসএসসি রেজাল্ট ২০১৯ । নাম্বার সহ এসএসসি, দাখিল ও ভোকেশনাল পরীক্ষার ফলাফল ২০১৯Breaking News

    Thursday, March 20, 2025

    New

    WELLCOME BACK

    H

    ello guys. How are you all? I hope you are all well. I came again with a post. Let’s go..

    তো নিয়ে এলাম Gemini Ai Chstbot পোস্ট। কথা হচ্ছে Chatbot তৈরি নিয়ে অনেক দিন চেষ্টা করছি কিন্তু কাজ করে না কিন্তু এবার পেয়ে গেছি।

    তো চলুন শুরু করা যাক।

    Gemini Ai

    Gemini Ai এর Api ব্যবহার করে এই Chatbot তৈরি করা হয়েছে Html, css, javascript দিয়ে। তাই এটি আপনি আপনার যেকোনো ওয়েবসাইট এ ব্যবহার করতে পারবেন।

    Live Demo

    তো ডেমো দেখে নিন।

    Demo:

    Screen shot



    সবার আগে আপনাকে Gemini Api key নিতে হবে। আমি সব দেখাচ্ছি তো চলুন।

    প্রথমে এই লিংক এ যান .. তারপর New Project তৈরি করুন।





    Search “Gemini” and click..

    Enable now


    Click & Api key generate

    Copy Api key

    এই Api key টা শুধু Javascript কোড এর এখানে বসাবেন।

    তো এখন কোড গুলে নিন।

    Html code

    
    <!DOCTYPE html>
    <!-- Coding By Hasan - facebook.com/SWEETxHASAN -->
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Gemini Chatbot | HASAN</title>
        <!-- Linking Google Fonts For Icons -->
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@32,400,0,0" />
        <link rel="stylesheet" href="/style.css" />
      </head>
      <body>
        <div class="container">
          <!-- App Header -->
          <header class="app-header">
            <h1 class="heading">Hello, there</h1>
            <h4 class="sub-heading">How can I help you today?</h4>
          </header>
    
          <!-- Suggestions List -->
          <ul class="suggestions">
            <li class="suggestions-item">
              <p class="text">Design a home office setup for remote work under $500.</p>
              <span class="icon material-symbols-rounded">draw</span>
            </li>
            <li class="suggestions-item">
              <p class="text">How can I level up my web development expertise in 2025?</p>
              <span class="icon material-symbols-rounded">lightbulb</span>
            </li>
            <li class="suggestions-item">
              <p class="text">Suggest some useful tools for debugging JavaScript code.</p>
              <span class="icon material-symbols-rounded">explore</span>
            </li>
            <li class="suggestions-item">
              <p class="text">Create a React JS component for the simple todo list app.</p>
              <span class="icon material-symbols-rounded">code_blocks</span>
            </li>
          </ul>
    
          <!-- Chats -->
          <div class="chats-container"></div>
    
          <!-- Prompt Input -->
          <div class="prompt-container">
            <div class="prompt-wrapper">
              <form action="#" class="prompt-form">
                <input type="text" placeholder="Ask Gemini" class="prompt-input" required />
                <div class="prompt-actions">
                  <!-- File Upload Wrapper -->
                  <div class="file-upload-wrapper">
                    <img src="#" class="file-preview" />
                    <input id="file-input" type="file" accept="image/*, .pdf, .txt, .csv" hidden />
                    <button type="button" class="file-icon material-symbols-rounded">description</button>
                    <button id="cancel-file-btn" type="button" class="material-symbols-rounded">close</button>
                    <button id="add-file-btn" type="button" class="material-symbols-rounded">attach_file</button>
                  </div>
    
                  <!-- Send Prompt and Stop Response Buttons -->
                  <button id="stop-response-btn" type="button" class="material-symbols-rounded">stop_circle</button>
                  <button id="send-prompt-btn" class="material-symbols-rounded">arrow_upward</button>
                </div>
              </form>
    
              <!-- Theme and Delete Chats Buttons -->
              <button id="theme-toggle-btn" class="material-symbols-rounded">light_mode</button>
              <button id="delete-chats-btn" class="material-symbols-rounded">delete</button>
            </div>
    
            <p class="disclaimer-text">Gemini can make mistakes, so double-check it.</p>
          </div>
        </div>
    
        <script src="/script.js"></script>
      </body>
    </html>
    

    CSS code

    
    /* Import Google Font - Poppins */
    @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");
    
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: "Poppins", sans-serif;
    }
    
    :root {
      /* Dark theme colors */
      --text-color: #edf3ff;
      --subheading-color: #97a7ca;
      --placeholder-color: #c3cdde;
      --primary-color: #101623;
      --secondary-color: #283045;
      --secondary-hover-color: #333e58;
      --scrollbar-color: #626a7f;
    }
    
    body.light-theme {
      /* Light theme colors */
      --text-color: #090c13;
      --subheading-color: #7b8cae;
      --placeholder-color: #606982;
      --primary-color: #f3f7ff;
      --secondary-color: #dce6f9;
      --secondary-hover-color: #d2ddf2;
      --scrollbar-color: #a2aac2;
    }
    
    body {
      color: var(--text-color);
      background: var(--primary-color);
    }
    
    .container {
      overflow-y: auto;
      padding: 32px 0 60px;
      height: calc(100vh - 127px);
      scrollbar-color: var(--scrollbar-color) transparent;
    }
    
    .container :where(.app-header, .suggestions, .message, .prompt-wrapper) {
      position: relative;
      margin: 0 auto;
      width: 100%;
      padding: 0 20px;
      max-width: 990px;
    }
    
    .container .app-header {
      margin-top: 3vh;
    }
    
    .app-header .heading {
      width: fit-content;
      font-size: 3rem;
      background: linear-gradient(to right, #1d7efd, #8f6fff);
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
    }
    
    .app-header .sub-heading {
      font-size: 2.6rem;
      margin-top: -5px;
      color: var(--subheading-color);
    }
    
    .container .suggestions {
      width: 100%;
      list-style: none;
      display: flex;
      gap: 15px;
      margin-top: 9.5vh;
      overflow-x: auto;
      scroll-snap-type: x mandatory;
      scrollbar-width: none;
    }
    
    body.chats-active .container :where(.app-header, .suggestions) {
      display: none;
    }
    
    .suggestions .suggestions-item {
      cursor: pointer;
      padding: 18px;
      width: 228px;
      flex-shrink: 0;
      display: flex;
      scroll-snap-align: center;
      flex-direction: column;
      align-items: flex-end;
      border-radius: 12px;
      justify-content: space-between;
      background: var(--secondary-color);
      transition: 0.3s ease;
    }
    
    .suggestions .suggestions-item:hover {
      background: var(--secondary-hover-color);
    }
    
    .suggestions .suggestions-item .text {
      font-size: 1.1rem;
    }
    
    .suggestions .suggestions-item .icon {
      width: 45px;
      height: 45px;
      display: flex;
      font-size: 1.4rem;
      margin-top: 35px;
      align-self: flex-end;
      align-items: center;
      border-radius: 50%;
      justify-content: center;
      color: #1d7efd;
      background: var(--primary-color);
    }
    
    .suggestions .suggestions-item:nth-child(2) .icon {
      color: #28a745;
    }
    
    .suggestions .suggestions-item:nth-child(3) .icon {
      color: #ffc107;
    }
    
    .suggestions .suggestions-item:nth-child(4) .icon {
      color: #6f42c1;
    }
    
    .container .chats-container {
      display: flex;
      gap: 20px;
      flex-direction: column;
    }
    
    .chats-container .message {
      display: flex;
      gap: 11px;
      align-items: center;
    }
    
    .chats-container .message .avatar {
      width: 43px;
      height: 43px;
      flex-shrink: 0;
      align-self: flex-start;
      border-radius: 50%;
      padding: 6px;
      margin-right: -7px;
      background: var(--secondary-color);
      border: 1px solid var(--secondary-hover-color);
    }
    
    .chats-container .message.loading .avatar {
      animation: rotate 3s linear infinite;
    }
    
    @keyframes rotate {
      100% {
        transform: rotate(360deg);
      }
    }
    
    .chats-container .message .message-text {
      padding: 3px 16px;
      word-wrap: break-word;
      white-space: pre-line;
    }
    
    .chats-container .bot-message {
      margin: 9px auto;
    }
    
    .chats-container .user-message {
      flex-direction: column;
      align-items: flex-end;
    }
    
    .chats-container .user-message .message-text {
      padding: 12px 16px;
      max-width: 75%;
      background: var(--secondary-color);
      border-radius: 13px 13px 3px 13px;
    }
    
    .chats-container .user-message .img-attachment {
      margin-top: -7px;
      width: 50%;
      border-radius: 13px 3px 13px 13px;
    }
    
    .chats-container .user-message .file-attachment {
      display: flex;
      gap: 6px;
      align-items: center;
      padding: 10px;
      margin-top: -7px;
      border-radius: 13px 3px 13px 13px;
      background: var(--secondary-color);
    }
    
    .chats-container .user-message .file-attachment span {
      color: #1d7efd;
    }
    
    .container .prompt-container {
      position: fixed;
      width: 100%;
      left: 0;
      bottom: 0;
      padding: 16px 0;
      background: var(--primary-color);
    }
    
    .prompt-container :where(.prompt-wrapper, .prompt-form, .prompt-actions) {
      display: flex;
      gap: 12px;
      height: 56px;
      align-items: center;
    }
    
    .prompt-container .prompt-form {
      height: 100%;
      width: 100%;
      border-radius: 130px;
      background: var(--secondary-color);
    }
    
    .prompt-form .prompt-input {
      width: 100%;
      height: 100%;
      background: none;
      outline: none;
      border: none;
      font-size: 1rem;
      color: var(--text-color);
      padding-left: 24px;
    }
    
    
    .prompt-form .prompt-input::placeholder {
      color: var(--placeholder-color);
    }
    
    .prompt-wrapper button {
      width: 56px;
      height: 100%;
      flex-shrink: 0;
      cursor: pointer;
      border-radius: 50%;
      font-size: 1.4rem;
      border: none;
      color: var(--text-color);
      background: var(--secondary-color);
      transition: 0.3s ease;
    }
    
    .prompt-wrapper :is(button:hover, #cancel-file-btn, .file-icon) {
      background: var(--secondary-hover-color);
    }
    
    .prompt-form .prompt-actions {
      gap: 5px;
      margin-right: 7px;
    }
    
    .prompt-wrapper .prompt-form :where(.file-upload-wrapper, button, img) {
      position: relative;
      height: 45px;
      width: 45px;
    }
    
    .prompt-form .prompt-actions #send-prompt-btn {
      color: #fff;
      display: none;
      background: #1d7efd;
    }
    
    .prompt-form .prompt-input:valid~.prompt-actions #send-prompt-btn {
      display: block;
    }
    
    .prompt-form #send-prompt-btn:hover {
      background: #0264e3;
    }
    
    .prompt-form .file-upload-wrapper :where(button, img) {
      display: none;
      border-radius: 50%;
      object-fit: cover;
      position: absolute;
    }
    
    .prompt-form .file-upload-wrapper.active #add-file-btn {
      display: none;
    }
    
    .prompt-form .file-upload-wrapper #add-file-btn,
    .prompt-form .file-upload-wrapper.active.img-attached img,
    .prompt-form .file-upload-wrapper.active.file-attached .file-icon,
    .prompt-form .file-upload-wrapper.active:hover #cancel-file-btn {
      display: block;
    }
    
    .prompt-form :is(#stop-response-btn:hover, #cancel-file-btn) {
      color: #d62939;
    }
    
    .prompt-wrapper .prompt-form .file-icon {
      color: #1d7efd;
    }
    
    .prompt-form #stop-response-btn,
    body.bot-responding .prompt-form .file-upload-wrapper {
      display: none;
    }
    
    body.bot-responding .prompt-form #stop-response-btn {
      display: block;
    }
    
    .prompt-container .disclaimer-text {
      font-size: 0.9rem;
      text-align: center;
      padding: 16px 20px 0;
      color: var(--placeholder-color);
    }
    
    /* Responsive media query code for small screens */
    @media (max-width: 768px) {
      .container {
        padding: 20px 0 100px;
      }
    
      .app-header :is(.heading, .sub-heading) {
        font-size: 2rem;
        line-height: 1.4;
      }
    
      .app-header .sub-heading {
        font-size: 1.7rem;
      }
    
      .container .chats-container {
        gap: 15px;
      }
    
      .chats-container .bot-message {
        margin: 4px auto;
      }
    
      .prompt-container :where(.prompt-wrapper, .prompt-form, .prompt-actions) {
        gap: 8px;
        height: 53px;
      }
    
      .prompt-container button {
        width: 53px;
      }
    
      .prompt-form :is(.file-upload-wrapper, button, img) {
        height: 42px;
        width: 42px;
      }
    
      .prompt-form .prompt-input {
        padding-left: 20px;
      }
    
      .prompt-form .file-upload-wrapper.active #cancel-file-btn {
        opacity: 0;
      }
    
      .prompt-wrapper.hide-controls :where(#theme-toggle-btn, #delete-chats-btn) {
        display: none;
      }
    }
    

    javascript code

    
    
    const container = document.querySelector(".container");
    const chatsContainer = document.querySelector(".chats-container");
    const promptForm = document.querySelector(".prompt-form");
    const promptInput = promptForm.querySelector(".prompt-input");
    const fileInput = promptForm.querySelector("#file-input");
    const fileUploadWrapper = promptForm.querySelector(".file-upload-wrapper");
    const themeToggleBtn = document.querySelector("#theme-toggle-btn");
    const suggestions = document.querySelector(".suggestions"); // Suggested Messages এলিমেন্ট
    
    // API Setup
    const API_KEY = "YOUR_API_KEY";
    const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-flash:generateContent?key=${API_KEY}`;
    
    let controller, typingInterval;
    let chatHistory = []; // চ্যাট হিস্টরি অ্যারে
    const userData = { message: "", file: {} };
    
    // Set initial theme from local storage
    const isLightTheme = localStorage.getItem("themeColor") === "light_mode";
    document.body.classList.toggle("light-theme", isLightTheme);
    themeToggleBtn.textContent = isLightTheme ? "dark_mode" : "light_mode";
    
    // Local Storage থেকে চ্যাট হিস্টরি লোড করুন
    const loadChatHistory = () => {
      const savedChats = localStorage.getItem("chatHistory");
      if (savedChats) {
        chatHistory = JSON.parse(savedChats);
        renderChatHistory();
      }
      toggleSuggestions(); // Suggested Messages টগল করুন
    };
    
    // Local Storage-এ চ্যাট হিস্টরি সংরক্ষণ করুন
    const saveChatHistory = () => {
      localStorage.setItem("chatHistory", JSON.stringify(chatHistory));
    };
    
    // Suggested Messages টগল করুন
    const toggleSuggestions = () => {
      if (chatHistory.length === 0) {
        suggestions.style.display = "flex"; // Suggested Messages দেখান
      } else {
        suggestions.style.display = "none"; // Suggested Messages লুকান
      }
    };
    
    // চ্যাট হিস্টরি UI-তে রেন্ডার করুন
    const renderChatHistory = () => {
      chatsContainer.innerHTML = ""; // আগের চ্যাট ক্লিয়ার করুন
      chatHistory.forEach((chat) => {
        if (chat.role === "user") {
          const userMsgHTML = `
            <p class="message-text">${chat.parts[0].text}</p>
            ${chat.parts[1]?.inline_data ? `<img src="data:${chat.parts[1].inline_data.mime_type};base64,${chat.parts[1].inline_data.data}" class="img-attachment" />` : ""}
          `;
          const userMsgDiv = createMessageElement(userMsgHTML, "user-message");
          chatsContainer.appendChild(userMsgDiv);
        } else if (chat.role === "model") {
          const botMsgHTML = `<img class="avatar" src="https://brandlogo.org/wp-content/uploads/2024/06/Gemini-Icon.png.webp" /> <p class="message-text">${chat.parts[0].text}</p>`;
          const botMsgDiv = createMessageElement(botMsgHTML, "bot-message");
          chatsContainer.appendChild(botMsgDiv);
        }
      });
      scrollToBottom();
    };
    
    // Function to create message elements
    const createMessageElement = (content, ...classes) => {
      const div = document.createElement("div");
      div.classList.add("message", ...classes);
      div.innerHTML = content;
      return div;
    };
    
    // Scroll to the bottom of the container (only if user is already at the bottom)
    const scrollToBottom = () => {
      const isScrolledToBottom = container.scrollTop + container.clientHeight >= container.scrollHeight - 50; // 50px tolerance
      if (isScrolledToBottom) {
        container.scrollTo({ top: container.scrollHeight, behavior: "smooth" });
      }
    };
    
    // Simulate typing effect for bot responses
    const typingEffect = (text, textElement, botMsgDiv) => {
      textElement.textContent = "";
      const words = text.split(" ");
      let wordIndex = 0;
    
      // Set an interval to type each word
      typingInterval = setInterval(() => {
        if (wordIndex < words.length) {
          textElement.textContent += (wordIndex === 0 ? "" : " ") + words[wordIndex++];
          scrollToBottom(); // Scroll to bottom only if user is at the bottom
        } else {
          clearInterval(typingInterval);
          botMsgDiv.classList.remove("loading");
          document.body.classList.remove("bot-responding");
        }
      }, 40); // 40 ms delay
    };
    
    // Make the API call and generate the bot's response
    const generateResponse = async (botMsgDiv) => {
      const textElement = botMsgDiv.querySelector(".message-text");
      controller = new AbortController();
    
      // Add user message and file data to the chat history
      chatHistory.push({
        role: "user",
        parts: [{ text: userData.message }, ...(userData.file.data ? [{ inline_data: (({ fileName, isImage, ...rest }) => rest)(userData.file) }] : [])],
      });
    
      try {
        // Send the chat history to the API to get a response
        const response = await fetch(API_URL, {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ contents: chatHistory }),
          signal: controller.signal,
        });
    
        const data = await response.json();
        if (!response.ok) throw new Error(data.error.message);
    
        // Process the response text and display with typing effect
        const responseText = data.candidates[0].content.parts[0].text.replace(/\*\*([^*]+)\*\*/g, "$1").trim();
        typingEffect(responseText, textElement, botMsgDiv);
    
        chatHistory.push({ role: "model", parts: [{ text: responseText }] });
        saveChatHistory(); // চ্যাট হিস্টরি সংরক্ষণ করুন
      } catch (error) {
        textElement.textContent = error.name === "AbortError" ? "Response generation stopped." : error.message;
        textElement.style.color = "#d62939";
        botMsgDiv.classList.remove("loading");
        document.body.classList.remove("bot-responding");
        scrollToBottom();
      } finally {
        userData.file = {};
      }
    };
    
    // Handle the form submission
    const handleFormSubmit = (e) => {
      e.preventDefault();
      const userMessage = promptInput.value.trim();
      if (!userMessage || document.body.classList.contains("bot-responding")) return;
    
      userData.message = userMessage;
      promptInput.value = "";
      document.body.classList.add("chats-active", "bot-responding");
      fileUploadWrapper.classList.remove("file-attached", "img-attached", "active");
    
      // Generate user message HTML with optional file attachment
      const userMsgHTML = `
        <p class="message-text"></p>
        ${userData.file.data ? (userData.file.isImage ? `<img src="data:${userData.file.mime_type};base64,${userData.file.data}" class="img-attachment" />` : `<p class="file-attachment"><span class="material-symbols-rounded">description</span>${userData.file.fileName}</p>`) : ""}
      `;
    
      const userMsgDiv = createMessageElement(userMsgHTML, "user-message");
      userMsgDiv.querySelector(".message-text").textContent = userData.message;
      chatsContainer.appendChild(userMsgDiv);
      scrollToBottom();
    
      // প্রথম মেসেজ পাঠানোর সাথে সাথেই Suggested Messages লুকান
      chatHistory.push({ role: "user", parts: [{ text: userData.message }] });
      toggleSuggestions(); // Suggested Messages লুকান
    
      setTimeout(() => {
        // Generate bot message HTML and add in the chat container
        const botMsgHTML = `<img class="avatar" src="https://brandlogo.org/wp-content/uploads/2024/06/Gemini-Icon.png.webp" /> <p class="message-text">Just a sec...</p>`;
        const botMsgDiv = createMessageElement(botMsgHTML, "bot-message", "loading");
        chatsContainer.appendChild(botMsgDiv);
        scrollToBottom();
        generateResponse(botMsgDiv);
      }, 600); // 600 ms delay
    };
    
    // Handle file input change (file upload)
    fileInput.addEventListener("change", () => {
      const file = fileInput.files[0];
      if (!file) return;
    
      const isImage = file.type.startsWith("image/");
      const reader = new FileReader();
      reader.readAsDataURL(file);
    
      reader.onload = (e) => {
        fileInput.value = "";
        const base64String = e.target.result.split(",")[1];
        fileUploadWrapper.querySelector(".file-preview").src = e.target.result;
        fileUploadWrapper.classList.add("active", isImage ? "img-attached" : "file-attached");
    
        // Store file data in userData obj
        userData.file = { fileName: file.name, data: base64String, mime_type: file.type, isImage };
      };
    });
    
    // Cancel file upload
    document.querySelector("#cancel-file-btn").addEventListener("click", () => {
      userData.file = {};
      fileUploadWrapper.classList.remove("file-attached", "img-attached", "active");
    });
    
    // Stop Bot Response
    document.querySelector("#stop-response-btn").addEventListener("click", () => {
      controller?.abort();
      userData.file = {};
      clearInterval(typingInterval);
      chatsContainer.querySelector(".bot-message.loading").classList.remove("loading");
      document.body.classList.remove("bot-responding");
    });
    
    // Toggle dark/light theme
    themeToggleBtn.addEventListener("click", () => {
      const isLightTheme = document.body.classList.toggle("light-theme");
      localStorage.setItem("themeColor", isLightTheme ? "light_mode" : "dark_mode");
      themeToggleBtn.textContent = isLightTheme ? "dark_mode" : "light_mode";
    });
    
    // Delete all chats
    document.querySelector("#delete-chats-btn").addEventListener("click", () => {
      chatHistory = [];
      localStorage.removeItem("chatHistory"); // Local Storage থেকে চ্যাট হিস্টরি ডিলিট করুন
      chatsContainer.innerHTML = "";
      document.body.classList.remove("chats-active", "bot-responding");
      toggleSuggestions(); // Suggested Messages দেখান
    });
    
    // Handle suggestions click
    document.querySelectorAll(".suggestions-item").forEach((suggestion) => {
      suggestion.addEventListener("click", () => {
        promptInput.value = suggestion.querySelector(".text").textContent;
        promptForm.dispatchEvent(new Event("submit"));
      });
    });
    
    // Show/hide controls for mobile on prompt input focus
    document.addEventListener("click", ({ target }) => {
      const wrapper = document.querySelector(".prompt-wrapper");
      const shouldHide = target.classList.contains("prompt-input") || (wrapper.classList.contains("hide-controls") && (target.id === "add-file-btn" || target.id === "stop-response-btn"));
      wrapper.classList.toggle("hide-controls", shouldHide);
    });
    
    // Add event listeners for form submission and file input click
    promptForm.addEventListener("submit", handleFormSubmit);
    promptForm.querySelector("#add-file-btn").addEventListener("click", () => fileInput.click());
    
    // পেজ লোড হওয়ার সময় চ্যাট হিস্টরি লোড করুন
    window.addEventListener("load", loadChatHistory);
      
    

    YOUR_API_KEY এখানে আপনার Api key বসাবেন।

    কেডগুলো যুক্ত করলে কাজ করবে।

    পরের পোস্ট এর জন্য অপেক্ষায় থাকুন আরো ভালো পোস্ট আসতে চলেছে।

    THE END

    S

    o friends, that’s it for today. See you in another post. If you like the post then like and comment. Stay tuned to Trickbd.com for any updates.

    The post কিভাবে Html, Css, Javascript দিয়ে Gemini Ai Chatbot তৈরি করবেন? appeared first on Trickbd.com.



    from Trickbd.com https://ift.tt/J0l4KzT
    via IFTTT

    No comments:

    Post a Comment

    Fashion

    Beauty

    Travel