1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

FlutterでX (旧Twitter) のリンクからOGP情報を取ってくる

Posted at

以下の記事を参考に、FlutterでOGP情報の表示ビューを作成しました。

しかし、x.comのポストのリンクについてはOGPの取得に失敗し、正常に表示できませんでした。これを表示できるようにするまでの流れを共有します。

OGP取得を成功させるために必要なポイントは2つありました。

  1. リクエストヘッダに"User-Agent: bot"をつける
  2. リダイレクトの処理にもヘッダーをつける

プログラム

最終的にうまく行ったプログラムは以下です。
metadata_fetchというライブラリを使っているので、

flutter pub add metadata_fetch

で追加してください。

get_ogp.dart
import 'package:metadata_fetch/metadata_fetch.dart';
import 'package:http/http.dart' as http;

Future<http.StreamedResponse> httpGetWithoutAutoRedirect(Uri uri) async {
    http.Request req = http.Request("Get", uri);
    req.followRedirects = false;
    req.headers["User-Agent"] = "bot";
    http.Client baseClient = http.Client();
    return await baseClient.send(req);
}

Future<Metadata> fetchMetaData(String url) async {
    var streamedResponse = await httpGetWithoutAutoRedirect(Uri.parse(url));
    
    //無限リダイレクトの回避のため最大5回までのループにしています
    for (var i = 0; streamedResponse.isRedirect && i < 5; i++) {
      final redirectURL = streamedResponse.headers["location"];
      if (redirectURL == null) {
        safePrint('fetching redirect url failed $url');
        break;
      }
      streamedResponse =
          await httpGetWithoutAutoRedirect(Uri.parse(redirectURL));
    }
    
    final response = await http.Response.fromStream(streamedResponse);
    
    final document = MetadataFetch.responseToDocument(response);
    return MetadataParser.parse(document, url: url);
    }
}

注意点

リクエストヘッダに"User-Agent: bot"をつける

twitter.comに普通にアクセスすると、ヘッダーにOGPのmetaデータが付いてこないようです。リクエスト時にヘッダーに"User-Agent: bot"をつけると付いてくるようになります。
↓こちらを参考にさせていただきました。

リダイレクトの処理にもヘッダーをつける

現在、Xの共有URLはx.comですが、これはtwitter.comへのリダイレクトURLになっています。Dartで普通にhttpリクエストを送るときは、

http.get(Uri.parse('https://example.com'), headers:{"User-Agent" : "bot"});

のようにな書き方になります。
この関数は与えられたURLがリダイレクトURLであれば、自動的にリダイレクト先まで辿ってレスポンスを返してくれます。しかし、どうやら辿る際に指定したヘッダーは無視されてしまうようです。これでは、Twitterのよううなmetaデータの取得に"User-Agent: bot"のヘッダーを要するサイトに対応できません。
そこで、リダイレクト時にもちゃんとヘッダーを送信し直してくれるような関数を自作する必要があります。
以下の部分がその関数です。

get_ogp.dart
Future<http.StreamedResponse> httpGetWithoutAutoRedirect(Uri uri) async {
    http.Request req = http.Request("Get", uri);
    req.followRedirects = false;
    req.headers["User-Agent"] = "bot";
    http.Client baseClient = http.Client();
    return await baseClient.send(req);
}

参考にした記事はこちら↓

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?