1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

O365ライブラリでGraph APIのカレンダー絡みのエラーを回避する

Last updated at Posted at 2025-06-08

はじめに

2025年6月上旬から、Graph APIでOutlookカレンダーの全ての予定表をGETしようとすると500 Internal Server Errorを吐く事態となった。
Graph Explorerで試してみると、以下のような反応が返ってくる。

GET https://graph.microsoft.com/v1.0/me/calendars

// レスポンス
{
    "error": {
        "code": "ErrorInternalServerError",
        "message": "An internal server error occurred. The operation failed."
    }
}

Internal Server Error - 500

解決策

X(Twitter)で検索をかけてみると、上記の問題を指摘し、Microsoftに修正を要求しているMark Messinger氏の投稿があった。

Messinger氏のスレッドの下の方を見てみると、どうやらconferenceフィールドを除いてGraph APIを呼び出すとOutlookカレンダーのすべての予定表が取得できるとのこと。

そこで、以下のようなクエリを足したうえでGraph APIを叩いてみるとMessinger氏の言う通り、Outlook予定表のデータを取得することができた。(Graph Explorerで確認済)

GET https://graph.microsoft.com/v1.0/me/calendars?$select=id,name,color,isDefaultCalendar

OK - 200

では、Pythonでどう動かすか?

私は普段、PythonとO365ライブラリを使って、Graph APIから情報を取得したり、操作したりしている。確かに、クエリを足せばGraph APIからカレンダーを取得できることは分かったが、O365のget_calendar()メソッドには残念ながら$selectパラメータを指定できるような引数は存在しない。どうにかしてO365でも$selectパラメータを指定してGETできるようにしたい。

O365ライブラリのcalendar.pyを直接編集する

Windowsならだいたい"C:\Users\hoge\AppData\Local\Programs\Python\Python3xx\Lib\site-packages\O365"とかにO365ライブラリのソースコードがある。
O365ライブラリのソースコードを探ってみると、APIを叩くURLを生成しているのは、connection.pyget()メソッドであることが分かった。

connection.py
    def get(self, url: str, params: Optional[dict] = None, **kwargs) -> Response:
        """Shorthand for self.oauth_request(url, 'get')

        :param str url: url to send get oauth request to
        :param dict params: request parameter to get the service data
        :param kwargs: extra params to send to request api
        :return: Response of the request
        :rtype: requests.Response
        """
        return self.oauth_request(url, "get", params=params, **kwargs)

このparams$selectパラメータの内容を渡せばいいことが分かる。

calendar.py
    def get_calendar(self, calendar_id=None, calendar_name=None, query=None):
    
        """
        省略
        """
        
        if calendar_id:
            # get calendar by it's id
            url = self.build_url(
                self._endpoints.get('get_calendar').format(id=calendar_id))
            params = {"$select": "id,name,color,isDefaultCalendar"} # 書き換え箇所
            # params = None
        else:
            # get calendar by name
            url = self.build_url(self._endpoints.get('root_calendars'))
            params = {
                '$filter': "{} eq '{}'".format(self._cc('name'), calendar_name),
                '$top': 1,
                "$select": "id,name,color,isDefaultCalendar"} # 書き換え箇所
            """ 
            params = {
                '$filter': "{} eq '{}'".format(self._cc('name'), calendar_name),
                '$top': 1}
            """
        
        response = self.con.get(url, params=params)
        """
        省略
        """

        # Everything received from cloud must be passed as self._cloud_data_key
        return self.calendar_constructor(parent=self,
                                         **{self._cloud_data_key: data})

あとは、calendar.pyget_calendarメソッドを書き換えて、con.get()$selectの内容を含んだparamsを読ませるようにする。

これで無事、Python+O365でもOutlookカレンダーが取得できるようになった。
というか、Microsoftは早くこのバグを直してくれヽ(`Д´)ノ

参考

python-o365 - github
Graph Explorer

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?