Discordボットトークンの入手方法

Discordボットトークンを入手する手順

  • Discordデベロッパーポータルにアクセス:

ブラウザで https://discord.com/developers/applications にアクセスします。

  • 新しいアプリケーションを作成:

右上の「New Application」ボタンをクリックします。
アプリケーション名を入力し、「Create」をクリックします。

  • ボットを作成:

左側のメニューから「Bot」を選択します。
「Add Bot」ボタンをクリックし、確認ダイアログで「Yes, do it!」を選択します。

  • ボット設定:

必要に応じてボットの名前やアイコンを設定します。

  • トークンの取得:

「Token」セクションの「Copy」ボタンをクリックしてトークンをコピーします。
注意: このトークンは秘密にしておく必要があります。

  • 必要な権限の設定:

「Privileged Gateway Intents」セクションで、ボットに必要な権限(例:メッセージ内容の読み取りなど)を有効にします。

  • ボットをサーバーに追加:

左側のメニューから「OAuth2」→「URL Generator」を選択します。
「Scopes」で「bot」にチェックを入れ、必要な権限を選択します。
生成されたURLをコピーし、新しいブラウザタブで開きます。
ボットを追加したいサーバーを選択し、認証を完了します。

  • トークンの使用:

コピーしたトークンを、先ほどのPythonコードのTOKEN変数に貼り付けます。

注意点:

  • トークンは秘密情報です。GitHubなどの公開リポジトリにアップロードしないよう注意してください。
  • ボットに必要最小限の権限のみを付与するのがベストプラクティスです。

これらの手順に従えば、Discordボットのトークンを取得し、プログラムで使用することができます。

Discord Botをサーバーに登録する手順

  • Discord Developer Portalにアクセス: https://discord.com/developers/applications にブラウザでアクセスし、ログインします。
  • アプリケーション(Bot)を選択: 既存のBotを使用する場合は、そのBotを選択します。新しいBotを作成する場合は、「New Application」をクリックして作成します。
  • OAuth2セクションに移動: 左側のメニューから「OAuth2」を選択し、さらに「URL Generator」をクリックします。
  • スコープとボット権限を選択:
    • a. 「Scopes」セクションで、以下にチェックを入れます:
      • bot
      • applications.commands(スラッシュコマンドを使用する場合)
    • b. 「Bot Permissions」セクションで、Botに必要な権限を選択します。最低限必要な権限は:
      • View Channels
      • Send Messages
      • Embed Links(リッチな埋め込みメッセージを送信する場合)
  • 招待リンクを生成: スコープと権限を選択すると、ページ下部に招待リンクが生成されます。
  • Botをサーバーに追加:
    • a. 生成された招待リンクをコピーし、新しいブラウザタブで開きます。
    • b. Botを追加したいサーバーを選択します。
    • c. 「継続」をクリックし、必要に応じて権限を確認します。
    • d. 「認証」をクリックしてBotをサーバーに追加します。
  • キャプチャ認証: セキュリティチェックのためのキャプチャが表示される場合があります。指示に従って完了してください。
  • 追加の確認: Discordアプリを開き、選択したサーバーにBotが追加されていることを確認します。

注意点:

  • サーバーにBotを追加するには、そのサーバーで「サーバーの管理」権限が必要です。
  • Botをサーバーに追加した後、サーバー設定でBotの役割(ロール)を確認し、必要に応じて権限を調整してください。
  • 特定のチャンネルでBotを使用したい場合は、そのチャンネルの権限設定も確認してください。

これらの手順に従えば、BotをDiscordサーバーに正常に追加できるはずです。追加後、Botが期待通りに動作しない場合は、権限設定を再確認するか、Botのコードやトークンが正しいことを確認してください。

FXの重要イベント(日本と米国だけ)を30分前にDiscordに投稿するpythonコード

1分に1回、タスクスケジューラ等で呼ぶこと前提。

import asyncio
from datetime import datetime, timedelta
import pytz
import requests
from bs4 import BeautifulSoup
import discord
import aiohttp

# Discordボットのトークン
DISCORD_TOKEN = 'Discordボットのトークン'
CHANNEL_ID = '投稿したいチャンネルのID'
def parse_time(date_str, time_str):
    try:
        # 日付と時間を結合
        datetime_str = f"{date_str} {time_str}"
        # 26:00 のような表記を処理
        if ':' in time_str:
            hours, minutes = map(int, time_str.split(':'))
            if hours >= 24:
                date_obj = datetime.strptime(date_str, "%m/%d")
                date_obj += timedelta(days=1)
                hours -= 24
                datetime_str = f"{date_obj.strftime('%m/%d')} {hours:02d}:{minutes:02d}"

        event_date = datetime.strptime(datetime_str, "%m/%d %H:%M")
        event_date = event_date.replace(year=datetime.now().year)
        return pytz.timezone('Asia/Tokyo').localize(event_date)
    except ValueError as e:
        print(f"Error parsing date/time: {e} for {date_str} {time_str}")
        return None

async def get_hirose_events():
    url = "https://hirose-fx.co.jp/contents/ecclndr/"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
    }
    async with aiohttp.ClientSession() as session:
        async with session.get(url, headers=headers) as response:
            print(f"Status Code: {response.status}")
            html_content = await response.text()
            print(f"Content length: {len(html_content)}")

    soup = BeautifulSoup(html_content, 'html.parser')

    events = []
    rows = soup.select('table.layout-top.row-data.font-small tr')

    current_date = None
    for row in rows:
        cells = row.select('td')
        if len(cells) >= 6:
            date_cell = cells[0].text.strip()
            time = cells[1].text.strip()
            currency = cells[2].find('img')['title'] if cells[2].find('img') else ''
            event_name = cells[3].text.strip()

            if date_cell:
                current_date = date_cell.split()[0]

            if current_date and time and currency in ['日本', '米国']:
                event_date = parse_time(current_date, time)
                if event_date:
                    events.append({
                        "name": f"{currency} - {event_name}",
                        "time": event_date
                    })

    print(f"Total JPY and USD events found: {len(events)}")
    return events

async def report_upcoming_events():
    fx_events = await get_hirose_events()
    now = datetime.now(pytz.timezone('Asia/Tokyo'))
    target_time = now + timedelta(minutes=30)
    upcoming_events = []

    for event in fx_events:
        time_until_event = event['time'] - now
        if timedelta(minutes=29) <= time_until_event <= timedelta(minutes=30):
            upcoming_events.append(event)

    if upcoming_events:
        message = "30分後に予定されている日本と米国のイベント:\n"
        for event in upcoming_events:
            message += f"{event['time'].strftime('%Y-%m-%d %H:%M')} - {event['name']}\n"

        # Discordに接続してメッセージを送信
        client = discord.Client(intents=discord.Intents.default())

        @client.event
        async def on_ready():
            try:
                channel = await client.fetch_channel(CHANNEL_ID)
                await channel.send(message)
                print(f"Message sent to channel {CHANNEL_ID}")
            finally:
                await client.close()

        await client.start(DISCORD_TOKEN)
    else:
        print("No events scheduled in the next 30 minutes.")

async def main():
    await report_upcoming_events()

if __name__ == "__main__":
    asyncio.run(main())

html&javascriptで、偶数日はindex1.html 奇数日はindex2.htmlを表示するようにする

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>日付に応じたリダイレクト</title>
</head>
<body>
    <script>
        // 現在の日付を取得
        const currentDate = new Date();
        
        // 日にちを取得(1-31)
        const dayOfMonth = currentDate.getDate();
        
        // 偶数日か奇数日かを判断し、適切なページにリダイレクト
        if (dayOfMonth % 2 === 0) {
            // 偶数日の場合
            window.location.href = 'index1.html';
        } else {
            // 奇数日の場合
            window.location.href = 'index2.html';
        }
    </script>
</body>
</html>

MFC top / left が 0 なら、親ウインドウの中心とこのウィンドウの中心が合うようにする

    // top / left が 0 なら、親ウインドウの中心とこのウィンドウの中心が合うようにする
    if (top == 0 && left == 0) {
        CWnd* pParentWnd = (CWnd*)GetParent();
        if (pParentWnd) 
        {
            CRect parentRect;
            pParentWnd->GetWindowRect(&parentRect);
            CRect dialogRect;
            GetWindowRect(&dialogRect);
            int parentCenterX = parentRect.left + (parentRect.Width() / 2);
            int parentCenterY = parentRect.top + (parentRect.Height() / 2);
            int dialogWidth = dialogRect.Width();
            int dialogHeight = dialogRect.Height();
            left = parentCenterX - (dialogWidth / 2);
            top = parentCenterY - (dialogHeight / 2);
        }
    }