<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>jidouka1221のブログ</title>
<link>https://ameblo.jp/jidouka1221/</link>
<atom:link href="https://rssblog.ameba.jp/jidouka1221/rss20.xml" rel="self" type="application/rss+xml" />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
<description>ブログの説明を入力します。</description>
<language>ja</language>
<item>
<title>”この記事に貼ってあるURLをコピペしてください。”</title>
<description>
<![CDATA[ <p>&nbsp;</p><p><iframe class="reblogCard" data-ameba-id="jidouka1221" data-entry-id="12885087960" frameborder="0" height="234px" sandbox="allow-same-origin allow-scripts allow-top-navigation" scrolling="no" src="https://ameblo.jp/s/embed/reblog-card/jidouka1221/entry-12885087960.html?reblogAmebaId=jidouka1221" width="100%"></iframe></p><p>&nbsp;</p>
]]>
</description>
<link>https://ameblo.jp/jidouka1221/entry-12885088087.html</link>
<pubDate>Tue, 04 Feb 2025 09:49:54 +0900</pubDate>
</item>
<item>
<title>こちらのコードを貼り付けてください</title>
<description>
<![CDATA[ <pre data-language="javascript"><code is:raw="">const THREADS_CLIENT_ID = 'YOUR_CLIENT_ID';const THREADS_CLIENT_SECRET = 'YOUR_CLIENT_SECRET';const THREADS_SCOPE = 'threads_basic,threads_content_publish';const THREADS_AUTH_URL = 'https://threads.net/oauth/authorize';const THREADS_TOKEN_URL = 'https://graph.threads.net/oauth/access_token';const THREADS_SPREADSHEET_ID = 'YOUR_SPREADSHEET_ID';function getServiceThreads() {    return OAuth2.createService('threads')        .setAuthorizationBaseUrl(THREADS_AUTH_URL)        .setTokenUrl(THREADS_TOKEN_URL)        .setClientId(THREADS_CLIENT_ID)        .setClientSecret(THREADS_CLIENT_SECRET)        .setCallbackFunction('authCallback')        .setPropertyStore(PropertiesService.getUserProperties())        .setScope(THREADS_SCOPE)        .setParam('access_type', 'offline')        .setParam('prompt', 'consent')        .setTokenHeaders({        'Authorization': 'Basic ' + Utilities.base64Encode(THREADS_CLIENT_ID + ':' + THREADS_CLIENT_SECRET)        });}function authCallback(request) {    var service = getServiceThreads();    var isAuthorized = service.handleCallback(request);    if (isAuthorized) {        return HtmlService.createHtmlOutput('認証成功！このウィンドウを閉じて、スクリプトエディタに戻ってください。');    } else {        return HtmlService.createHtmlOutput('認証に失敗しました。もう一度お試しください。');    }}function getAuthorizationUrl() {    var service = getServiceThreads();    if (!service.hasAccess()) {        var authorizationUrl = service.getAuthorizationUrl();        Logger.log('以下のURLにアクセスして認証を行ってください:');        Logger.log(authorizationUrl);        return authorizationUrl;    } else {        Logger.log('すでに認証されています。');        return null;    }}function getThreadsToken() {    var service = getServiceThreads();    if (service.hasAccess()) {        var accessToken = service.getAccessToken();        Logger.log('Access Token: ' + accessToken);        var response = UrlFetchApp.fetch(        'https://graph.threads.net/me?fields=id',        {            headers: {            Authorization: 'Bearer ' + accessToken            }        }        );        var userId = JSON.parse(response.getContentText()).id;        Logger.log('User ID: ' + userId);        return {            access_token: accessToken,            user_id: userId        };    } else {        Logger.log('認証が必要です。getAuthorizationUrl()を実行してください。');        return null;    }}function postToThreads() {    if (!checkAndRefreshToken()) {        Logger.log('トークンの更新に失敗しました。再認証が必要です。');        return;    }    var tokenData = getThreadsToken();    if (!tokenData) {        Logger.log('トークンの取得に失敗しました。認証を確認してください。');        return;    }    const CREATE_URL = `https://graph.threads.net/v1.0/${tokenData.user_id}/threads`;    const PUBLISH_URL = `https://graph.threads.net/v1.0/${tokenData.user_id}/threads_publish`;    const sheet = SpreadsheetApp.openById(THREADS_SPREADSHEET_ID).getActiveSheet();    const data = sheet.getDataRange().getValues();    let candidates = [];    let minPostCount = Infinity;    for (let i = 0; i &lt; data.length; i++) {        if (i === 0 &amp;&amp; (data[i][0] === 'ID' || data[i][1] === '投稿内容')) {            continue;        }        let postCount = data[i][2] || 0;        if (typeof postCount === 'string') postCount = parseInt(postCount, 10) || 0;        if (postCount &lt;= minPostCount) {            if (postCount &lt; minPostCount) {                candidates = [];                minPostCount = postCount;            }            candidates.push({ content: data[i][1], rowIndex: i });        }    }    if (candidates.length === 0) {        Logger.log('投稿する内容がありません。');        return;    }    const selected = candidates[Math.floor(Math.random() * candidates.length)];    const content = selected.content;    const createOptions = {        method: "post",        headers: {            "Authorization": "Bearer " + tokenData.access_token,            "Content-Type": "application/x-www-form-urlencoded"        },        payload: {            text: content,            media_type: "TEXT",            access_token: tokenData.access_token        }    };    try {        const createResponse = UrlFetchApp.fetch(CREATE_URL, createOptions);        if (createResponse.getResponseCode() === 200) {            const creationId = JSON.parse(createResponse.getContentText()).id;            const publishOptions = {                method: "post",                headers: {                    "Authorization": "Bearer " + tokenData.access_token,                    "Content-Type": "application/x-www-form-urlencoded"                },                payload: {                    creation_id: creationId,                    access_token: tokenData.access_token                }            };            const publishResponse = UrlFetchApp.fetch(PUBLISH_URL, publishOptions);            if (publishResponse.getResponseCode() === 200) {                Logger.log("投稿成功: " + content);                let currentCount = sheet.getRange(selected.rowIndex + 1, 3).getValue() || 0;                sheet.getRange(selected.rowIndex + 1, 3).setValue(currentCount + 1);                sheet.getRange(selected.rowIndex + 1, 4).setValue(new Date());            } else {                Logger.log("投稿の公開に失敗: " + content + ", ステータスコード: " + publishResponse.getResponseCode());                Logger.log("レスポンス: " + publishResponse.getContentText());            }        } else {            Logger.log("スレッドの作成に失敗: " + content + ", ステータスコード: " + createResponse.getResponseCode());            Logger.log("レスポンス: " + createResponse.getContentText());        }    } catch (error) {        Logger.log("エラー発生: " + error);    }}function checkAndRefreshToken() {    var service = getServiceThreads();    if (service.hasAccess()) {        Logger.log('トークンは有効です。');        return true;    } else {        Logger.log('トークンが無効または期限切れです。更新を試みます。');        try {        if (service.refresh()) {            Logger.log('トークンを更新しました。');            return true;        } else {            Logger.log('トークンの更新に失敗しました。再認証が必要です。');            return false;        }        } catch (e) {        Logger.log('エラーが発生しました: ' + e.toString());        Logger.log('再認証が必要です。getAuthorizationUrl()を実行してください。');        return false;        }    }}function clearStoredToken() {    PropertiesService.getUserProperties().deleteProperty('oauth2.threads');    Logger.log('保存されていたトークンをクリアしました。');}</code></pre>
]]>
</description>
<link>https://ameblo.jp/jidouka1221/entry-12885086085.html</link>
<pubDate>Tue, 04 Feb 2025 09:33:12 +0900</pubDate>
</item>
</channel>
</rss>
