LoginSignup
5
5

More than 5 years have passed since last update.

Mastodon API を Ruby(Faraday) / Python(Pycurl) / PHP(Curl) で叩いてみた

Posted at

マストドンをとりあえず叩いてみました。
表題の通り、Ruby は Faraday、Python は Pycurl、PHP は Curl を使っています。
app.xx でアプリ登録を行い、test.xx で認証〜投稿の流れとしました。

Ruby

app.rb
#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-

require 'faraday'
require 'uri'

CALLBACK_URL = 'アプリの URL'
MASTODON_URL = '対象とするインスタンスの URL(例: https://mstdn.high-low.ml)'
SCOPE = '欲しい権限(例: read write)'

options = {
  client_name: 'アプリの名前',
  redirect_uris: CALLBACK_URL,
  scopes: SCOPE
}

conn = Faraday.new(:url => MASTODON_URL) do |faraday|
  faraday.request :url_encoded
  faraday.response :logger
  faraday.adapter Faraday.default_adapter
end
response = conn.post do |request|
  request.url '/api/v1/apps'
  request.body = URI.encode_www_form(options)
end
print "Content-Type: application/json; charset=UTF-8\n\n"
print response.body

出力結果に表示された「client_id」と「client_secret」を保存します。

test.rb
#!/usr/local/bin/ruby
# -*- coding: utf-8 -*-

require 'cgi'
require 'uri'

cgi = CGI.new()

CALLBACK_URL = 'アプリの URL'
MASTODON_URL = '対象とするインスタンスの URL'
CLIENT_ID = 'app.rb で取得した CLIENT_ID'
CLIENT_SECRET = 'app.rb で取得した CLIENT_SECRET'
SCOPE = '指定した権限'

if cgi['code'].empty?
  # 認証を取りに行きます
  options = {
    client_id: CLIENT_ID,
    response_type: 'code',
    scope: SCOPE,
    redirect_uri: CALLBACK_URL
  }
  print cgi.header({
    'status' => 'REDIRECT',
    'Location' => "#{MASTODON_URL}/oauth/authorize?#{URI.encode_www_form(options)}"
  })
else
  # 認証されたので access_token を取りにいきます
  require 'faraday'
  require 'json'

  options = {
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET,
    grant_type: 'authorization_code',
    redirect_uri: CALLBACK_URL,
    scope: SCOPE,
    code: cgi['code']
  }

  conn = Faraday.new(:url => MASTODON_URL) do |faraday|
    faraday.request :url_encoded
    faraday.response :logger
    faraday.adapter Faraday.default_adapter
  end
  response = conn.post do |request|
    request.url '/oauth/token'
    request.body = URI.encode_www_form(options)
  end
  access_token = JSON.parse(response.body)['access_token']

  # access_token を取れたついでに、世間の中心でぱおーんと叫びます
  options = {
    mastodon_host: MASTODON_URL,
    status: 'ぱおーん'
  }
  response = conn.post do |request|
    request.url '/api/v1/statuses'
    request.headers = {
      'Authorization' => "Bearer #{access_token}"
    }
    request.body = URI.encode_www_form(options)
  end
  print "Content-Type: application/json; charset=UTF-8\n\n"
  print response.body
end

認証画面はこんな感じです。
スクリーンショット 2017-04-19 17.37.07.png

Python

app.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import pycurl, urllib
from StringIO import StringIO

CALLBACK_URL = 'アプリの URL'
MASTODON_URL = '対象とするインスタンスの URL'
SCOPE = '欲しい権限(例: read write)'

options = {
    'client_name': 'アプリの名前',
    'redirect_uris': CALLBACK_URL,
    'scopes': SCOPE
}

response = StringIO()
curl = pycurl.Curl()
curl.setopt(pycurl.URL, '%s/api/v1/apps' %(MASTODON_URL))
curl.setopt(pycurl.WRITEFUNCTION, response.write)
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.POSTFIELDS, urllib.urlencode(options))
curl.perform()
print "Content-Type: application/json; charset=UTF-8\n\n"
print response.getvalue()
test.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib, cgi
from StringIO import StringIO

form = cgi.FieldStorage()

CALLBACK_URL = 'アプリの URL'
MASTODON_URL = '対象とするインスタンスの URL'
CLIENT_ID = 'app.py で取得した CLIENT_ID'
CLIENT_SECRET = 'app.py で取得した CLIENT_SECRET'
SCOPE = '指定した権限'

if not form.has_key('code'):
    # 認証を取りにいきます
    options = {
        'client_id': CLIENT_ID,
        'response_type': 'code',
        'scope': SCOPE,
        'redirect_uri': CALLBACK_URL
    }
    print "Content-Type: text/html\n\n"
    print '<meta http-equiv=\"refresh\" content=\"0; URL=%s/oauth/authorize?%s\">' %(MASTODON_URL, urllib.urlencode(options))
else:
    # access_token を取りにいきます
    import pycurl, json

    options = {
        'client_id': CLIENT_ID,
        'client_secret': CLIENT_SECRET,
        'grant_type': 'authorization_code',
        'redirect_uri': CALLBACK_URL,
        'scope': SCOPE,
        'code': form['code'].value
    }

    response = StringIO()
    curl = pycurl.Curl()
    curl.setopt(pycurl.URL, '%s/oauth/token' %(MASTODON_URL))
    curl.setopt(pycurl.WRITEFUNCTION, response.write)
    curl.setopt(pycurl.POST, 1)
    curl.setopt(pycurl.POSTFIELDS, urllib.urlencode(options))
    curl.perform()
    access_token = str(json.loads(response.getvalue())['access_token'])

    # ぱおーんと叫びます
    options = {
        'mastodon_host': MASTODON_URL,
        'status': 'ぱおーん'
    }

    curl.setopt(pycurl.URL, '%s/api/v1/statuses' %(MASTODON_URL))
    curl.setopt(pycurl.HTTPHEADER, ['Authorization: Bearer %s' %(access_token)])
    curl.setopt(pycurl.POSTFIELDS, urllib.urlencode(options))
    curl.perform()

    print "Content-Type: application/json; charset=UTF-8\n\n"
    print response.getvalue()

PHP

app.php
<?php
define('CALLBACK_URL', 'アプリの URL');
define('MASTODON_URL', '対象とするインスタンスの URL(例: https://mstdn.high-low.ml)');
define('SCOPE', '欲しい権限(例: read write)');

$options = array(
    'client_name' => 'アプリの名前',
    'redirect_uris' => CALLBACK_URL,
    'scopes' => SCOPE
);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, MASTODON_URL. '/api/v1/apps');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

$response = curl_exec($ch);
curl_close($ch);

header('Content-type: application/json; charset=utf-8');
echo $response;
test.php
<?php
define('CALLBACK_URL', 'アプリの URL');
define('MASTODON_URL', '対象とするインスタンスの URL');
define('CLIENT_ID', 'app.php で取得した CLIENT_ID');
define('CLIENT_SECRET', 'app.php で取得した CLIENT_SECRET');
define('SCOPE', '指定した権限');

if (!isset($_GET['code'])) {
    # 認証
    $options = array(
        'client_id' => CLIENT_ID,
        'response_type' => 'code',
        'scope' => SCOPE,
        'redirect_uri' => CALLBACK_URL
    );
    header('Location: '. MASTODON_URL. '/oauth/authorize?'. http_build_query($options, '', '&'));
} else {
    # access_token 取得
    $options = array(
        'client_id' => CLIENT_ID,
        'client_secret' => CLIENT_SECRET,
        'grant_type' => 'authorization_code',
        'redirect_uri' => CALLBACK_URL,
        'scope' => SCOPE,
        'code' => $_GET['code']
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, MASTODON_URL. '/oauth/token');
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $response = curl_exec($ch);
    $data = json_decode($response);
    $access_token = $data->access_token;

    # ぱおーん
    $options = array(
        'mastodon_host' => MASTODON_URL,
        'status' => 'ぱおーん'
    );

    curl_setopt($ch, CURLOPT_URL, MASTODON_URL. '/api/v1/statuses');
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("Authorization: Bearer {$access_token}"));
    curl_setopt($ch, CURLOPT_POSTFIELDS, $options);
    $response = curl_exec($ch);
    curl_close($ch);
    header('Content-type: application/json; charset=utf-8');
    echo $response;
}

参考

tootsuite/mastodon-api: A ruby interface for the Mastodon API
MastodonのAPIをcurlで叩いてみるサンプル - Qiita
Mastodon API の叩き方

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5