オウム返しアプリを作成中にはまったこと(HTTPError: HTTP Error 401: Unauthorized編) Python&Lambda&APIGateway

#今回のエラー内容
[ERROR] HTTPError: HTTP Error 401: Unauthorized
Traceback (most recent call last):

#使用技術
python3.8
AWS lambda
AWS APIGateway
Line Message API

#参考サイト
https://blog.5000164.jp/2017/8/14/line-bot/

#今回の概要
![完成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299864/77becca6-b9ce-9e8f-9060-8b7ef83e6f84.png)
![さらに詳細図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1299864/3ac48ffd-8ad8-3cca-63c7-7a794ced6487.png)

#lambda_function.py に打ち込んだコード
```lambda_function.py
import logging

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

import base64
import hashlib
import hmac

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(request, context):
    
    # リクエストの検証を行う
    channel_secret = os.environ['LINE_CHANNEL_SECRET']
    body = request.get('body', '')
    hash = hmac.new(channel_secret.encode('utf-8'), body.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(hash).decode('utf-8')

    # LINE 以外からのアクセスだった場合は処理を終了させる
    #if signature != request.get('headers').get('X-Line-Signature', ''):
        #logger.info(f'LINE 以外からのアクセス request={request}')
        #return {'statusCode': 200, 'body': '{}'}    
    
    logger.info("リクエスト内容")
    logger.info(request)
    
    for event in json.loads(request['body'])['events']:
        logger.info(json.dumps(event))
        
        url = "https://api.line.me/v2/bot/message/reply"
        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + os.environ['LINE_CHANNEL_ACCESS_TOKEN']
        }
        logger.info(headers)
        logger.info(event['replyToken'])
        body = {
            'replyToken': event['replyToken'],
            'messages': [
                {
                    "type": "text",
                    "text": event['message']['text'],
                }
            ]
        }

        req = urllib.request.Request(url, data=json.dumps(body).encode('utf-8'), method='POST', headers=headers)

        with urllib.request.urlopen(req) as res:
            logger.info(res.read().decode("utf-8"))

    return {
        "statusCode": 200,
        "body": json.dumps("Hello from Lambda!")
    }
```
#本編
今回上図の構成で、製作中に HTTPError: HTTP Error 401: Unauthorized のエラーに詰まったので共有する。単刀直入に言うと　Line Messaging API が今回のAWSLambdaを認証する際に使う　Channel access token　が Google の翻訳機能により半角が入り権限が付与されなかったという内容だった。初めはLine Developer が英語表記になっているので、Google 翻訳を使って日本語に変えたいと思う。しかし、今回のようなaccess token を取得する際は本来の言語でコピーすることを心がけたい！

#今回の教訓
もっと英語を勉強して、元の言語で読めるようになる！！！！！！


#今回のアプリの派生
かき氷を取得すると、いちごと出力する。

```lambda_function2.py
import logging

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

import base64
import hashlib
import hmac

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(request, context):

    # リクエストの検証を行う
    channel_secret = os.environ['LINE_CHANNEL_SECRET']
    body = request.get('body', '')
    hash = hmac.new(channel_secret.encode('utf-8'), body.encode('utf-8'), hashlib.sha256).digest()
    signature = base64.b64encode(hash).decode('utf-8')

  

    logger.info("リクエスト内容")
    logger.info(request)

    for event in json.loads(request['body'])['events']:
        # 反応する発言内容を絞り込む
        if event['message']['text'] != 'かき氷':
            continue
        
        logger.info(json.dumps(event))

        url = "https://api.line.me/v2/bot/message/reply"
        headers = {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + os.environ['LINE_CHANNEL_ACCESS_TOKEN']
        }
        logger.info(headers)
        logger.info(event['replyToken'])
        body = {
            'replyToken': event['replyToken'],
            'messages': [
                {
                    "type": "text",
                    "text": 'いちご',
                }
            ]
        }

        req = urllib.request.Request(url, data=json.dumps(body).encode('utf-8'), method='POST', headers=headers)

        with urllib.request.urlopen(req) as res:
            logger.info(res.read().decode("utf-8"))

    return {
        "statusCode": 200,
        "body": json.dumps("Hello from Lambda!")
    }
```