soumyadeepdas/tbl_WebBotPublic · Community Store Listing

Demo WebApp

ProfileTelegram
14 commands0 envUpdated 19d agoCreated Oct 27, 2025
Back to folder

commands/membership.html.js

javascript · 275 lines · click line # to share

1/**#command2name: membership.html3answer: 4keyboard: 5parse_mode: 6aliases: 7allow_only_group: false8need_reply: false9is_web: 010#command**/11 12<!DOCTYPE html>13<html lang="en">14<head>15<meta charset="UTF-8">16<meta name="viewport" content="width=device-width, initial-scale=1.0">17<title>Membership Checker | TeleBotHost Demo</title>18<script src="https://telegram.org/js/telegram-web-app.js"></script>19<style>20  :root { color-scheme: dark; }21  body {22    margin: 0;23    font-family: "Poppins", sans-serif;24    background: linear-gradient(135deg, #0d1117 0%, #161b22 100%);25    color: #e6edf3;26    display: flex;27    flex-direction: column;28    align-items: center;29    padding: 20px 16px;30    min-height: 100vh;31  }32  .container {33    width: 100%;34    max-width: 480px;35    display: flex;36    flex-direction: column;37    align-items: center;38  }39  h1 {40    font-size: 1.5rem;41    font-weight: 600;42    margin-bottom: 10px;43    text-align: center;44    background: linear-gradient(90deg, #3fb950, #238636);45    -webkit-background-clip: text;46    background-clip: text;47    color: transparent;48  }49  .description {50    text-align: center;51    margin-bottom: 28px;52    color: #8b949e;53    font-size: 0.9rem;54    max-width: 80%;55  }56  .channel-list {57    width: 100%;58    display: flex;59    flex-direction: column;60    gap: 14px;61  }62  .channel-item {63    display: flex;64    justify-content: space-between;65    align-items: center;66    background: rgba(22, 27, 34, 0.7);67    padding: 16px 18px;68    border-radius: 14px;69    transition: all 0.3s ease;70    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);71    border: 1px solid #30363d;72  }73  .channel-item:hover {74    background: rgba(28, 33, 40, 0.8);75    transform: translateY(-2px);76    box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15);77  }78  .channel-info {79    display: flex;80    align-items: center;81    gap: 12px;82  }83  .channel-icon {84    width: 36px;85    height: 36px;86    border-radius: 50%;87    background: linear-gradient(135deg, #238636, #3fb950);88    display: flex;89    align-items: center;90    justify-content: center;91    font-size: 1.2rem;92  }93  .channel-details {94    display: flex;95    flex-direction: column;96  }97  .channel-name {98    font-size: 1rem;99    font-weight: 500;100  }101  .channel-status {102    font-size: 0.8rem;103    margin-top: 2px;104  }105  .status-joined {106    color: #3fb950;107  }108  .status-not-joined {109    color: #f85149;110  }111  .status-checking {112    color: #8b949e;113  }114  .action-buttons {115    display: flex;116    gap: 8px;117  }118  .check-btn, .join-btn, .check-again-btn {119    border: none;120    border-radius: 8px;121    color: #fff;122    font-size: 0.85rem;123    padding: 8px 16px;124    cursor: pointer;125    transition: all 0.2s ease;126    font-weight: 500;127  }128  .check-btn {129    background: #238636;130  }131  .check-btn:hover {132    background: #2ea043;133    transform: scale(1.05);134  }135  .join-btn {136    background: #da3633;137  }138  .join-btn:hover {139    background: #f85149;140    transform: scale(1.05);141  }142  .check-again-btn {143    background: #3fb950;144  }145  .check-again-btn:hover {146    background: #56d364;147    transform: scale(1.05);148  }149  .joined-badge {150    color: #3fb950;151    font-weight: 600;152    display: flex;153    align-items: center;154    gap: 6px;155  }156  .loader {157    width: 16px;158    height: 16px;159    border: 2px solid #30363d;160    border-top: 2px solid #3fb950;161    border-radius: 50%;162    animation: spin 1s linear infinite;163  }164  @keyframes spin { to { transform: rotate(360deg); } }165  .footer {166    margin-top: 30px;167    text-align: center;168    color: #8b949e;169    font-size: 0.8rem;170  }171</style>172</head>173<body>174  <div class="container">175    <h1>📢 Channel Membership Checker</h1>176    <p class="description">Check if you've joined our Telegram channels and get access to exclusive content</p>177    178    <div class="channel-list" id="channelList"></div>179    180    <div class="footer">181      <p>Powered by TeleBotHost</p>182    </div>183  </div>184  185  <script>186    let user = { id: 123456 };187    if (window.Telegram && Telegram.WebApp) {188      Telegram.WebApp.ready();189      const tgUser = Telegram.WebApp.initDataUnsafe?.user;190      if (tgUser) user = tgUser;191    }192    193    // Using EJS variable for channels194    const channels = <%= JSON.stringify(channels) %>;195    const apiBaseUrl = '<%= membership_api_url %>';196    197    const list = document.getElementById("channelList");198    199    channels.forEach((ch) => {200      const div = document.createElement("div");201      div.className = "channel-item";202      div.innerHTML = `203        <div class="channel-info">204          <div class="channel-icon">📢</div>205          <div class="channel-details">206            <span class="channel-name">${ch.name}</span>207            <span class="channel-status status-checking">Click check to verify</span>208          </div>209        </div>210        <div class="action-buttons">211          <button class="check-btn">Check</button>212        </div>213      `;214      215      const statusElement = div.querySelector(".channel-status");216      const btn = div.querySelector(".check-btn");217      const actionButtons = div.querySelector(".action-buttons");218      219      const checkMembership = async () => {220        btn.disabled = true;221        btn.innerHTML = '<div class="loader"></div>';222        statusElement.textContent = "Checking membership...";223        statusElement.className = "channel-status status-checking";224        225        try {226          // Construct API URL based on your demo227          const apiUrl = `${apiBaseUrl}?user_id=${user.id}&channels=${encodeURIComponent(ch.id)}`;228          229          const res = await fetch(apiUrl);230          const data = await res.json();231          232          if (data.status === "success") {233            // Check if user has joined this specific channel234            const hasJoined = data.membership_status.all_joined;235            236            if (hasJoined) {237              statusElement.textContent = "You're a member!";238              statusElement.className = "channel-status status-joined";239              actionButtons.innerHTML = '<span class="joined-badge">✅ Joined</span>';240            } else {241              statusElement.textContent = "You haven't joined yet";242              statusElement.className = "channel-status status-not-joined";243              actionButtons.innerHTML = `244                <button class="join-btn">Join Channel</button>245                <button class="check-again-btn">Check Again</button>246              `;247              248              // Add event listeners to new buttons249              const joinBtn = actionButtons.querySelector(".join-btn");250              const checkAgainBtn = actionButtons.querySelector(".check-again-btn");251              252              joinBtn.addEventListener("click", () => {253                window.open(`https://t.me/${ch.id.replace('@', '')}`, '_blank');254              });255              256              checkAgainBtn.addEventListener("click", checkMembership);257            }258          } else {259            throw new Error('API returned unsuccessful status');260          }261        } catch (error) {262          console.error("Error checking membership:", error);263          statusElement.textContent = "Error checking status";264          statusElement.className = "channel-status status-not-joined";265          btn.disabled = false;266          btn.textContent = "Retry";267        }268      };269      270      btn.addEventListener("click", checkMembership);271      list.appendChild(div);272    });273  </script>274</body>275</html>