Google App EngineのPythonで無料でLINE Botを作るというチャレンジをしているのですが、GitHubで公開されているLineのline-bot-sdk-pythonがflask前提となっていたので、flaskを使わないようなプログラムがほしいなと思い、急遽自作することに。
今回は、EventのTypeを取得するメソッドを実装します。
linebot.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2007 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
import logging
import hashlib
import hmac
import base64
import json
import urllib2
class LineWebhookEventClass(object):
def __init__(self,request_body):
self._request_body = request_body.decode('utf-8').encode('utf-8')
json_dict = json.loads(self._request_body)
self.events = json_dict["events"]
self.eventsLen = len(self.events)
def _event(self,idx):
if idx >= self.eventsLen:
return None
if idx < 0:
return None
return self.events[idx]
def eventType(self,idx):
_event = self._event(idx)
if _event:
return _event["type"]
else:
return None
class LineSendMessageClass(object):
def __init__(self,access_token):
self._reply_message_api = "https://api.line.me/v2/bot/message/reply"
self._push_message_api = "https://api.line.me/v2/bot/message/push"
self._access_token = access_token
def _header(self):
return {
"Content-Type":"application/json",
"Authorization":("Bearer <%s>" % self._access_token)
}
def replyMessage(self,reply_token,*messages):
_form_data = {
"replyToken":reply_token,
"messages":messages
}
_form_data = json.dumps(_form_data)
_req = urllib2.Request(self._reply_message_api,_form_data,self._header())
_f = urllib2.urlopen(_req)
_response= _f.read()
_f.close()
def pushMessage(self,to,*msg):
_form_data = {
"to":to,
"messages":msg
}
_form_data = json.dumps(_form_data)
_req = urllib2.Request(self._push_message_api,_form_data,self._header())
_f = urllib2.urlopen(_req)
_response= _f.read()
logging.info(_response)
_f.close()
class LineWebhookClass(object):
def __init__(self):
pass
@classmethod
def isValidSignature(cls,channel_secret,x_line_signature,request_body):
_request_body = request_body.decode('utf-8').encode('utf-8')
hsh = hmac.new(channel_secret.encode('utf-8'),_request_body,hashlib.sha256).digest()
signature = base64.b64encode(hsh)
if signature == x_line_signature:
return True
else:
return False
class LineTemplateActionClass(object):
def __init__(self):
pass
@classmethod
def _text(cls,text):
_text_max_length = 300
#unicode型ではない場合
if not isinstance(text,unicode):
return None
#300文字より大きい場合は、300文字に変更する
if len(text) > _text_max_length:
return text[0:_text_max_length]
return text
@classmethod
def _label(cls,label):
_label_max_length = 20
#unicode型ではない場合
if not isinstance(label,unicode):
return None
#20文字より大きい場合は、20文字に変更する
if len(label) > _label_max_length:
return label[0:_label_max_length]
return label
@classmethod
def postbackAction(cls,label,data,text):
_label = cls._label(label)
if _label is None:
return None
_text = cls._text(text)
if _text is None:
return None
_data = data
_data_max_length = 300
# unicode型ではない場合
if not isinstance(_data,unicode):
return None
#300文字より大きい場合は、300文字に変更する
if len(_data) > _data_max_length:
_data = _data[0:_data_max_length]
return {
"type":"postback",
"label":_label,
"text":_text,
"data":_data
}
@classmethod
def uriAction(cls,label,uri):
_label = cls._label(label)
if _label is None:
return None
_uri = uri
_uri_max_length = 1000
#string型ではない場合
if not isinstance(uri,unicode):
return None
#1000文字より大きい場合は Noneを返す
if len(_uri) > _uri_max_length:
return None
return {
"type":"uri",
"label":_label,
"uri":_uri
}
@classmethod
def messageAction(cls,label,text):
_label = cls._label(label)
if _label is None:
return None
_text = cls._text(text)
if _text is None:
return None
return {
"type":"message",
"label":_label,
"text":_text
}
class LineTemplateMessageClass(object):
def __init__(self):
pass
@classmethod
def _baseTemplateMessage(cls,alttext):
_alttext = alttext
_alttext_max_length = 400
#unicode型ではない場合
if not isinstance(_alttext,unicode):
return None
#400文字より大きい場合は、20文字に変更する
if len(_alttext) > _alttext_max_length:
_alttext = _alttext[0:_alttext_max_length]
return {
"type":"template",
"altText":_alttext
}
@classmethod
def _button(cls,thumbnailimageurl,title,text,*actions):
_title_max_length = 40
_title = title
#unicode型ではない場合
if not isinstance(_title,unicode):
return None
#40文字より大きい場合は、40文字に変更する
if len(_title) > _title_max_length:
_title = _title[0:_title_max_length]
_text = text
_text_max_length = 60
if not isinstance(_text,unicode):
return None
#60文字より大きい場合は、60文字に変更する
if len(_text) > _text_max_length:
_text = _text[0:_text_max_length]
return {
"thumbnailImageUrl":thumbnailimageurl,
"title":_title,
"text":_text,
"actions":actions
}
@classmethod
def carousel(cls,alttext,*columns):
_carousel = cls._baseTemplateMessage(alttext)
if _carousel is None:
return None
_columns = []
for i in range(0,len(columns)):
_column = columns[i]
_columns.append(cls._button(_column["thumbnailimageurl"],_column["title"],_column["text"],*_column["actions"]))
_carousel["template"] = {
"type":"carousel",
"columns":_columns
}
return _carousel
@classmethod
def buttons(cls,alttext,thumbnailimageurl,title,text,*actions):
_buttons = cls._baseTemplateMessage(alttext)
if _buttons is None:
return None
_template = {
"type":"buttons"
}
_template.update(
cls._button(thumbnailimageurl,title,text,*actions)
)
_buttons["template"] = _template
return _buttons
@classmethod
def confirm(cls,alttext,text,*actions):
_confirm = cls._baseTemplateMessage(alttext)
if _confirm is None:
return None
_text_max_length = 240
_text = text
#unicode型ではない場合
if not isinstance(_text,unicode):
return None
#400文字より大きい場合は、20文字に変更する
if len(_text) > _text_max_length:
_text = _text[0:_text_max_length]
_confirm["template"] = {
"type":"confirm",
"text":_text,
"actions":actions
}
return _confirm
0 コメント:
コメントを投稿