LoginSignup
3
4

More than 3 years have passed since last update.

AWS LambdaでSlackに添付ファイルとして投稿(Python)

Posted at

Amazon S3からファイルを取得してSlackに添付ファイルとして投稿するAWS Lambdaを作っていたが、AWS LambdaのPython環境にはrequestsモジュールが入っていなかったので苦戦した。

前提・環境

AWS Lambda Python環境

やりたかった事

  1. Amazon S3からファイルを取得する
  2. ファイルをSlackのfiles.upload APIで添付ファイルとして投稿する(content typeはmultipart/form-dataを使う)

できなかったこととその理由

Pythonでのファイルのアップロードは、
https://qiita.com/5zm/items/92cde9e043813e02eb68

https://www.it-swarm-ja.tech/ja/python/python%E3%81%A7%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%A8-multipart-formdata%E3%82%92%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%EF%BC%9F/1069592211/
にあるように、requestsを使うのが定番。
しかしAWS LambdaのPython環境にはrequestsモジュールが入っていなかった。

解決方法

  • requestsの含まれるLambda Layerを使う
  • requestsではなくurllib.requestを使う <- 採用

実装

urllib.requestを使うと言ってもmultipart form dataを作成する必要があるので以下のURLを参考にした。
https://necoyama3.hatenablog.com/entry/20150608/1434982490
この記事内に記載にあるencode_multipart_formdataメソッドはデータ部とファイル部をmultipart form dataの形式に変換してくれる。

これを利用して以下のようにした。

## ポイント1: fileパラメータを除いたパラメータを定義する
data = {
   'token': <your token>,
   'channels': <your channels>,
   'initial_comment': key + 'を投稿します:eyes:',
   'filename': key,
   'filetype': 'webp'
}

url = "https://slack.com/api/files.upload"
content = open('/tmp/' + key, 'rb').read()

## ポイント2: fileパラメータを定義する
file = {'file': {'filename': key, 'content': content}}

## ポイント3: dataとfileをひとつのmultipart form dataに変換する
content_type, body = encode_multipart_formdata(data, file)

header = {'Content-Type': content_type}
request = urllib.request.Request(url, body, header)
response = urllib.request.urlopen(request)

ポイントになるのは
1. data変数でSlack files.upload APIのfileパラメータを除いたパラメータを定義する
2. file変数でSlack files.upload APIのfileパラメータを定義する
3. encode_multipart_formdataメソッドでmultipart form dataに変換する

の3点。
これでrequestsを使わずにAWS LambdaでSlackにファイルを投稿できるようになった。

最後に

Lambda Layerを作るのとどちらが楽なんだろうか…?

3
4
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
3
4