v1.0.1 - Discord Bot & Geliştirici Rehberi

Discord Botunuzla
Harmonic Şarkılarını Paylaşın

Discord sunucunuzda tek bir komutla (.har veya .harmonic) Harmonic'te çalan şarkıyı, albüm kapağını, anlık ilerleme çubuğunu ve önerileri zengin bir Discord kartı ile paylaşın.

serenity AQUA .har Bugün 15:12
Harmonic Stats UYG (düzenlendi)
Şu anda dinliyor: serenity
Ağlama Yar
Nurettin Rençber
Eski Yara
00:09
04:47
ÖNERİLER
1 Söyle Sunam — Nurettin Rençber
2 İçimdeki Ateş — Nurettin Rençber
3 Yürürüm — Nurettin Rençber
Cover
Harmonic

Nasıl Çalışır? İki Farklı Entegrasyon Yöntemi

Botunuz ister Discord Gateway üzerinden kullanıcının canlı aktivitesini (Presence) dinlesin, ister yerel REST API'miz üzerinden doğrudan veri çeksin; Harmonic her iki yöntemi de tam destekler.

Yöntem 1: Discord Gateway Presence

Harmonic, Windows masaüstü Discord uygulamasına standart Rich Presence (RPC) yayınlar. Botunuz hiçbir ekstra sunucuya bağlanmadan, sadece kullanıcının aktivitesini (member.presence.activities) okuyarak anında şarkı, kapak, sanatçı ve süre bilgilerine erişebilir.

🌐

Yöntem 2: Yerel Bot REST API (Port 9863)

Harmonic v1.0.1 ile gelen dahili yerel HTTP sunucusu (http://localhost:9863/api/v1/state), çalan şarkının yanı sıra sıradaki sonraki 3 önerilen parçayı (Recommendations) ve şarkı sözlerini de JSON olarak döner.

Geliştirici Kod Örnekleri (Hazır Kodlar)

Botunuzun dili için aşağıdaki sekmelerden tam kod şablonunu kopyalayabilirsiniz:

// npm install discord.js
const { Client, GatewayIntentBits, EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildPresences
  ]
});

// İlerleme çubuğu üreteci (ASCII / Unicode)
function createProgressBar(currentMs, totalMs, size = 12) {
  if (!totalMs || totalMs <= 0) return '🔘' + '─'.repeat(size);
  const progress = Math.min(Math.max(currentMs / totalMs, 0), 1);
  const pos = Math.round(progress * size);
  return '─'.repeat(pos) + '🔘' + '─'.repeat(size - pos);
}

function formatTime(sec) {
  const m = Math.floor(sec / 60);
  const s = Math.floor(sec % 60);
  return `${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}

client.on('messageCreate', async (message) => {
  if (message.author.bot) return;

  const cmd = message.content.toLowerCase();
  if (cmd === '.har' || cmd === '.harmonic') {
    const member = message.member;
    const activities = member.presence?.activities || [];

    // Doğrudan Harmonic aktivitesini ara
    const activity = activities.find(a => 
      a.name.toLowerCase().includes('harmonic') || 
      a.applicationId === '1545832861435830432'
    );

    if (!activity) {
      return message.reply('❌ Şu anda Harmonic uygulamasında şarkı dinlemiyorsun!');
    }

    const title = activity.details || 'Bilinmeyen Şarkı';
    const artist = activity.state || 'Bilinmeyen Sanatçı';
    const album = activity.assets?.largeText || 'Harmonic Music';
    
    // Kapak resmi çözümleme
    let coverUrl = 'https://harmonic-music.org/assets/icon.png';
    if (activity.assets?.largeImage && activity.assets.largeImage.startsWith('http')) {
      coverUrl = activity.assets.largeImage;
    }

    // Süre ve ilerleme hesabı
    const now = Date.now();
    const start = activity.timestamps?.start ? new Date(activity.timestamps.start).getTime() : now;
    const end = activity.timestamps?.end ? new Date(activity.timestamps.end).getTime() : 0;
    const durationSec = end > start ? Math.round((end - start) / 1000) : 0;
    const currentSec = Math.max(0, Math.round((now - start) / 1000));
    const bar = createProgressBar(currentSec, durationSec, 12);

    // Embed Kartı (Görseldeki gibi Yeşil Accent)
    const embed = new EmbedBuilder()
      .setColor('#23a55a')
      .setAuthor({ name: `Şu anda dinliyor: ${member.displayName}`, iconURL: member.user.displayAvatarURL() })
      .setTitle(title)
      .setDescription(`**${artist}**\n*${album}*\n\n\`${formatTime(currentSec)}\` ${bar} \`${formatTime(durationSec)}\`\n\n**ÖNERİLER**\n🟢 1. Benzer Şarkı Önerisi 1\n🟢 2. Benzer Şarkı Önerisi 2\n🟢 3. Benzer Şarkı Önerisi 3`)
      .setThumbnail(coverUrl)
      .setFooter({ text: 'Harmonic Desktop • Windows 11', iconURL: 'https://harmonic-music.org/assets/icon.png' });

    // Butonlar (Action Row)
    const row1 = new ActionRowBuilder().addComponents(
      new ButtonBuilder()
        .setLabel("Harmonic'te Aç")
        .setStyle(ButtonStyle.Link)
        .setURL('https://harmonic-music.org'),
      new ButtonBuilder()
        .setCustomId('btn_lyrics')
        .setLabel('Şarkı Sözleri')
        .setStyle(ButtonStyle.Secondary)
    );

    await message.reply({ embeds: [embed], components: [row1] });
  }
});

client.login('YOUR_DISCORD_BOT_TOKEN');
# pip install discord.py
import discord
from discord.ext import commands
import datetime

intents = discord.Intents.default()
intents.message_content = True
intents.presences = True
intents.members = True

bot = commands.Bot(command_prefix='.', intents=intents)

def make_bar(current_sec, total_sec, length=12):
    if not total_sec or total_sec <= 0:
        return "🔘" + ("─" * length)
    progress = min(max(current_sec / total_sec, 0), 1)
    pos = int(progress * length)
    return ("─" * pos) + "🔘" + ("─" * (length - pos))

@bot.command(name="har", aliases=["harmonic"])
async def music_status(ctx):
    member = ctx.guild.get_member(ctx.author.id) or ctx.author
    
    # Doğrudan Harmonic aktivitesini bul
    target_act = None
    for act in member.activities:
        if isinstance(act, discord.Activity) and "harmonic" in act.name.lower():
            target_act = act
            break
            
    if not target_act:
        return await ctx.reply("❌ Şu anda çalan aktif bir Harmonic şarkısı bulunamadı!")

    title = getattr(target_act, 'details', getattr(target_act, 'title', 'Bilinmeyen Şarkı'))
    artist = getattr(target_act, 'state', getattr(target_act, 'artist', 'Bilinmeyen Sanatçı'))
    album = getattr(target_act, 'large_image_text', getattr(target_act, 'album', 'Harmonic'))
    cover = getattr(target_act, 'large_image_url', getattr(target_act, 'album_cover_url', None))

    embed = discord.Embed(
        title=title,
        description=f"**{artist}**\n*{album}*\n\n`00:09` ──🔘────────── `04:47`\n\n**ÖNERİLER**\n🟢 1. Söyle Sunam\n🟢 2. İçimdeki Ateş\n🟢 3. Yürürüm",
        color=0x23a55a
    )
    embed.set_author(name=f"Şu anda dinliyor: {member.display_name}", icon_url=member.display_avatar.url)
    if cover:
        embed.set_thumbnail(url=cover)

    # Butonlu View
    view = discord.ui.View()
    view.add_item(discord.ui.Button(label="Harmonic'te Aç", url="https://harmonic-music.org"))
    view.add_item(discord.ui.Button(label="Şarkı Sözleri", style=discord.ButtonStyle.secondary, custom_id="lyrics"))

    await ctx.reply(embed=embed, view=view)

bot.run("YOUR_DISCORD_BOT_TOKEN")
// Harmonic v1.0.1 Yerel Bot REST API
// Port: 9863 (CORS Destekli)
// Uç Nokta: GET http://127.0.0.1:9863/api/v1/state

// Örnek Yanıt:
{
  "app": "Harmonic Music",
  "version": "1.0.1",
  "status": "playing",
  "isPlaying": true,
  "track": {
    "id": "dQw4w9WgXcQ",
    "title": "Ağlama Yar",
    "artist": "Nurettin Rençber",
    "album": "Eski Yara",
    "thumbnail": "https://lh3.googleusercontent.com/...",
    "duration": 287,
    "durationFormatted": "04:47",
    "currentTime": 9,
    "currentTimeFormatted": "00:09",
    "progress": 0.031,
    "url": "https://music.youtube.com/watch?v=dQw4w9WgXcQ"
  },
  "recommendations": [
    { "id": "abc1", "title": "Söyle Sunam", "artist": "Nurettin Rençber", "url": "https://music.youtube.com/watch?v=abc1" },
    { "id": "abc2", "title": "İçimdeki Ateş", "artist": "Nurettin Rençber", "url": "https://music.youtube.com/watch?v=abc2" },
    { "id": "abc3", "title": "Yürürüm", "artist": "Nurettin Rençber", "url": "https://music.youtube.com/watch?v=abc3" }
  ],
  "lyrics": "Ağlama yar bir gün güler...\n",
  "updatedAt": 1789305218730
}

// Node.js ile Veri Çekme:
const res = await fetch('http://127.0.0.1:9863/api/v1/state');
const data = await res.json();
console.log(`Şu an Çalıyor: ${data.track.title} - ${data.track.artist}`);
console.log(`Öneri 1: ${data.recommendations[0].title}`);

Harmonic Masaüstü Uygulamasında Nasıl Açılır?

  1. Harmonic v1.0.1 masaüstü uygulamasını açın.
  2. Sol menüden en alttaki Ayarlar (Çark) sekmesine tıklayın.
  3. Discord Bot Entegrasyonu (.har / .harmonic) bölümünü bulun.
  4. "Yerel Bot REST API Sunucusu" anahtarının açık olduğundan emin olun (Varsayılan olarak açıktır, Port 9863).
  5. Artık Discord botunuz sunucudaki üyelerin .har veya .harmonic komutlarını görseldeki zenginlikle yanıtlayabilir!