2
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?

slackのbotに天気を教えてもらう(Python on AWS Lambda + API Gateway)

Posted at

はじめに

前回の続きにはなりますが、Lambda関数内のPythonコードを変換して、実用編をやってみましたので、良かったら見ていってください。
【前回のURL】

全体構成

Slack → API Gateway → AWS Lambda (Python) → WeatherAPI(無料)

前提

・WeatherAPIの無料アカウントを登録し、APIキーを取得済み

・Lambdaの環境変数に SLACK_BOT_TOKEN, WEATHER_API_KEY を設定済み

・API Gateway で Slack Events を受け取れるように設定済み(Slack bot構築済)

Lambdaコード(WeatherAPI対応)

import json
import os
import urllib.request
import urllib.parse

SLACK_TOKEN = os.environ['SLACK_BOT_TOKEN']
WEATHER_API_KEY = os.environ['WEATHER_API_KEY']

def lambda_handler(event, context):
    body = json.loads(event['body'])

    # SlackのURL検証対応
    if 'challenge' in body:
        return {
            "statusCode": 200,
            "body": body['challenge']
        }

    if body.get("event") and body["event"].get("type") == "app_mention":
        text = body["event"].get("text", "")
        channel = body["event"]["channel"]
        user = body["event"]["user"]

        if "天気" in text:
            city = extract_city(text)
            weather_info = get_weather(city)
            message = f"<@{user}> {city}の天気:\n{weather_info}"
        else:
            message = f"<@{user}> コマンドが分かりません。`天気 <都市名>` を入力してください。"

        send_slack_message(channel, message)

    return {
        'statusCode': 200,
        'body': 'OK'
    }

def extract_city(text):
    parts = text.split("天気", 1)
    return parts[1].strip() if len(parts) > 1 else "Tokyo"

def get_weather(city):
    base_url = "http://api.weatherapi.com/v1/current.json"
    params = urllib.parse.urlencode({
        "key": WEATHER_API_KEY,
         "q": city,
        "lang": "ja"
    })  # ← ← ← ここでしっかり閉じます

    url = f"{base_url}?{params}"

    try:
        with urllib.request.urlopen(url) as response:
            data = json.loads(response.read())
            location = data["location"]["name"]
            condition = data["current"]["condition"]["text"]
            temp_c = data["current"]["temp_c"]
            return f"{location} の天気は「{condition}」、気温は {temp_c}℃ です。"
    except Exception as e:
        print(f"Weather API Error: {e}")
        return "天気情報の取得に失敗しました。都市名を確認してください。"
        
def send_slack_message(channel, text):
    url = "https://slack.com/api/chat.postMessage"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {SLACK_TOKEN}"
    }
    data = json.dumps({
        "channel": channel,
        "text": text
    }).encode("utf-8")
    req = urllib.request.Request(url, data=data, headers=headers)
    with urllib.request.urlopen(req) as res:
        print(res.read())


SlackのBotとの会話

image.png

# おわりに
Lambda関数のコード変換で、詰まることが何度か発生しました。
【手詰まり部分】
・括弧 { ... } をしっかり }) で閉じる。
・コンマ(,) 抜け
・インデントを揃えていない。
 例:def send_slack_message() が except: ブロックの中に定義されているように見え、構文エラーとなる。

まだまだ、Pythonの勉強が必要だなと感じました(笑)

2
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
2
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?