GASからXへ投稿（2025年5月時点版）

# はじめに
**GASからXへ投稿する**ことを調べてみると、情報は案外たくさんあって、コピペでできそうってなりますが、**全然できません**。

たぶん、Xのログインに関する仕様が変更されセキュリティの堅さが上がって、これまでの方法ではできなくなってるんじゃないかと。調べて出てくる情報は、その仕様変更にまだ、追いついていないのが多いのではないかと。

たぶん、`access_token`と`refresh_token`を取得する方法が堅くなって、その次の`access_token`を利用するあたりは変わってないと推測します。

そのせいかなんかわかりませんが、ChatGPT君に聞いてもいまいち。

ということで、**やってダメだったこと** と、**やってできたこと** をまとめます。あと、**これ危ない** っていう話も。

この記事は2025/5/12時点の話です。

最終的に実現できたソースはこちら。この記事自体ではざっくりとしか説明しません。

https://github.com/yo16/gas_x_post2

# やってダメだったこと１選：Google公式ライブラリの使用
Google製のOAuth2.0のライブラリがあります。ネットで調べて案外たくさんある情報は、ほぼすべて、Google公式ライブラリの使用なので、１選となります。🙇‍♂️

https://github.com/googleworkspace/apps-script-oauth2

ご丁寧に、samplesの下にはTwitter.gsまである。嬉しい。🥰

と思いきや、これをそのまま使ってもダメ。案外たくさんある情報もいろいろ試しても結局ダメ。

認証画面が出て「認証！」って押すと、**「トークンが無効か、有効期限が切れています。もう一度お試しください。」** というメッセージが出ます。OAuth2.0関連で問題が起こると、誰がエラーを出しているのかわからなくて、困ります。**今回も結局わかってない**。

Authorizationはできるけど、そのあとに呼ばれるはずの、`.setCallbackFunction('authCallback')`で指定する`authCallback()`が呼ばれてないようなんですよね。
むしろ呼ばれる仕組みが全然わからなくて、ChatGPTに聞いたりしたけど、**今も結局わかってない**。

なんだかわからないけど動かせられない！というお話でした。このOAuth2.0ライブラリは、XのAPIだけではなく他の用途にも使えるから、そのときはうまく動くのかもしれない😉

なおXのAPIの仕様変更は、2023年ごろのようで1年以上前なので、「ダメだった」と書いたものの、私の知識不足である可能性も否めません。

# できた方法：OAuth2.0の通信をfetchでやる
OAuth2.0の仕組みは、それこそ調べればたくさん出てくるし、これはもう世界標準だから正しい方法も決まってる。それを実装するだけ。Xでは、PKCEという小技も加わるけど、それも調べれば正解がある。

正確な方法は、、、**地味に調べてください**🙄
「OAuth2.0の通信を、自前でfetchでやる」なんていう人は、調べないとできないです。

いちおう手順は次の通り

1. `access_token`入手まで
    1. AuthorizationのURLを作り出す(with PKCE)
    1. そのURLをブラウザで開く
    1. 「このXのアカウント使っていい？」って聞かれるからOKという
    1. GASの`doGet()`が呼ばれ、そのときのURLパラメータの`code`を覚えておく
    1. `code`を使って、`access_token`を入手する
2. 投稿まで
    1. Xへの投稿のAPIを呼び出す。そのときに`access_token`を使う
    1. もし`access_token`が使用期限切れと言われたら、`refresh_token`を使って、新しい`access_token`と`refresh_token`をゲットする
    1. Xへの投稿のX-APIを呼び出す

なお、Google製のOAuth2.0ライブラリではやらなくてよいことで、この **手作りな方法だとやらなくちゃいけない大きなこと** が１つあります。それは、コールバック周りのこと。

1-4で「`doGet()`が呼ばれ」のところ。これはコールバックURIとして、デプロイしたウェブアプリのURLを指定する必要があります。デプロイしたウェブアプリのURLは、ちょっと独特。
- URLは、デプロイしないと確定しない
- URLは、GASのプログラムの中で、固定値として使う
- URLは、X Developer Portalの中に設定する必要がある

この３つを満たすために、
1. デプロイしてURLをゲット
1. `PropertiesService.getScriptProperties().setProperty("REDIRECT_URI", "～～～～デプロイURL～～～");`とセット（プログラム用）
    - 使うときは、`PropertiesService.getScriptProperties().getProperty("REDIRECT_URI");`
1. X Developer Portalへ設定

という手順を踏みます。GASの中で、自分のデプロイURLを取得できれば2は省けると思ったけど、これは諸事情でできないとのこと。気持ち悪いけどまぁ、１回やるだけなので、いいでしょう。

# "これは危ない"の話
GASの開発は、まずはブラウザでやるんだけど、今どきとてもじゃないけどできず、VSCodeなりCursorなりでやるじゃないですか。そうするとその勢いでgithubへ登録するじゃないですか。

一方でGASは、環境変数とか機密情報の変数とかを格納する機能がないので、何も考えないとべた書きしたくなるじゃないですか。ブラウザで書いてるときは問題ないし。

その２つが合わさると、**ID/パスワードがgithubへ流出する** という事故が起こります。なお流出するとすぐ検知され、数分で使われるとのこと。怖っっっ！💀

## 対策（かなり苦しいけど）
コード上は、`PropertiesService.getScriptProperties().getProperty("SECRET")`で取得することにしておく。そこへ設定するコードは`PropertiesService.getScriptProperties().setProperty("SECRET", "***");`とか適当に書いておく。

次に、それをGASへpushし、gitへもpushする。

最後に、GASのブラウザの画面で、`"***"`の部分を編集して、保存。

・・・気をつけましょう。（実は今回やらかして、リポジトリごと消し、SECRETも再作成しました）

# まとめ
**Make.comがXへの投稿モジュールを使えなくする**というリリースを出し、Make界隈がざわつきました。もともとXへの自動投稿は怪しかったけども、2025年5月末で**ちゃんと使えなくなる**と。

今回のOAuth2.0を直接使う方法であれば、GASであろうがPythonであろうがMake(モジュールを使わない方法)であろうが、大体何からでもいけるので、１つ成功事例を持っておくとよいと思いました。少し前にPythonとMakeでやったので、今回は割と楽でした。

ではよき地味に調べるライフを！