def report_to_slack(cls, msg, file_path): try: slack_client = SlackClient(API_TOKEN) classname = cls.__class__.__name__ slack_client.send_message(SLACK_CHANNEL, f"[{classname}] : {msg}") slack_client.upload_file(SLACK_CHANNEL, "image", file_path, None) except: pass
import os import logging import time from slackbot.slackclient import SlackClient import dotenv logging.basicConfig(level=logging.DEBUG) dotenv.load_dotenv(verbose=True) token = os.environ["SLACKBOT_API_TOKEN"] client = SlackClient(token) client.ping() client.send_message("#random", "hello") client.rtm_send_message("#random", "hello from RTM") print("hai") time.sleep(1) print("hoi")
def sendDM(text, target): sc = client(API_TOKEN) client.send_message(channel=target, message=text)
class ReportPublisher(threading.Thread): """ ITBトークンの利用状況に関するレポートを発行するクラス """ def __init__(self): super(ReportPublisher, self).__init__() self.setDaemon(False) self._db_context = DBContext() self._slackclient = SlackClient(API_TOKEN) self._should_stop = False self._interval = 3600 def run(self): """ スレッドを開始します。 """ self._should_stop = False while not self._should_stop: start_time = time.time() self._db_context.session.expire_all() # 現在時刻を取得する current_datetime = datetime.datetime.today().astimezone(timezone('Asia/Tokyo')) # 平日の場合 if current_datetime.weekday() in [0, 1, 2, 3, 4]: # 朝10時の場合 if current_datetime.hour == 10: for channel_id in REPORT_CHANNELS: self._slackclient.send_message( channel_id, "昨日のITBトークンの利用状況を報告します。" ) # 総幸福量(Gross Happiness)に関するレポートを発行する self.publish_grosshappiness(channel_id, current_datetime-datetime.timedelta(days=1)) # ITBカフェの売上高に関するレポートを発行する self.publish_sales(channel_id, current_datetime-datetime.timedelta(days=1)) past_time = time.time() - start_time if past_time < self._interval: time.sleep(self._interval - past_time) def publish_grosshappiness(self, channel_id: str, designated_date: datetime.datetime): """ いいね!総生産量に関するレポートを発行します。 """ date_from = datetime.datetime(*designated_date.timetuple()[:3]) date_to = date_from + datetime.timedelta(days=1) amount = self._db_context.session \ .query(func.sum(WithdrawalRequest.amount)) \ .filter(WithdrawalRequest.symbol == Symbol.ITB) \ .filter(WithdrawalRequest.updated_at >= date_from) \ .filter(WithdrawalRequest.updated_at < date_to) \ .all()[0][0] if amount is None: amount = Decimal("0") self._slackclient.send_message( channel_id, "昨日のいいね!総生産量は「{:.0f} ITB」でした。" .format(amount) ) def publish_sales(self, channel_id: str, designated_date: datetime.datetime): """ ITBカフェの売上高に関するレポートを発行します。 """ date_from = datetime.datetime(*designated_date.timetuple()[:3]) date_to = date_from + datetime.timedelta(days=1) amount = self._db_context.session \ .query(func.sum(ShopOrder.price)) \ .filter(ShopOrder.ordered_at >= date_from) \ .filter(ShopOrder.ordered_at < date_to) \ .all()[0][0] if amount is None: amount = Decimal("0") self._slackclient.send_message( channel_id, "昨日のITBカフェ売上高は「{:.0f} ITB」でした。" .format(amount) ) def request_stop(self): """ スレッドの停止をリクエストします。 """ self._should_stop = True
def sendDM(self, text, target): sc = client(API_TOKEN) client.send_message(self=sc, channel=target, message=text)
class WithdrawalExecutor(threading.Thread): """ 送金依頼を監視し、送金するクラス """ def __init__(self): super(WithdrawalExecutor, self).__init__() self.setDaemon(False) self._db_context = DBContext() self._slackclient = SlackClient(API_TOKEN) self._should_stop = False self._withdrawal_interval = 1 def run(self): """ スレッドを開始します。 """ self._should_stop = False while not self._should_stop: start_time = time.time() self._db_context.session.expire_all() # 休息中の送金元リスト updated_from = (datetime.datetime.now() - datetime.timedelta(seconds=60)).astimezone( timezone('UTC')) rest_address = self._db_context.session \ .query(distinct(WithdrawalRequest.from_address)) \ .filter(WithdrawalRequest.updated_at >= updated_from) \ .all() rest_address = list(map(lambda x: x[0], rest_address)) # 未着手の送金依頼を取得する prompt = self._db_context.session.query(WithdrawalRequest) \ .filter(WithdrawalRequest.is_success.is_(None)) \ .filter(WithdrawalRequest.from_address.notin_(rest_address)) \ .order_by(asc(WithdrawalRequest.symbol), asc(WithdrawalRequest.id)) \ .first() # 未着手の送金依頼を取得できた場合 if prompt: # 送金元・送金先・送金目的が同一の依頼を再取得する requests = self._db_context.session.query(WithdrawalRequest) \ .filter(WithdrawalRequest.is_success.is_(None)) \ .filter(WithdrawalRequest.from_address == prompt.from_address) \ .filter(WithdrawalRequest.to_address == prompt.to_address) \ .filter(WithdrawalRequest.purpose == prompt.purpose) \ .order_by(asc(WithdrawalRequest.id)) \ .all() # 未着手の送金依頼を取得できない場合 else: # エラーとなった送金依頼を取得する prompt = self._db_context.session.query(WithdrawalRequest) \ .filter(WithdrawalRequest.is_success == False) \ .order_by(asc(WithdrawalRequest.id)) \ .first() if prompt: requests = [prompt] else: requests = [] if len(requests) > 0: # 送金元ユーザーを取得する if requests[0].from_address == ITB_FOUNDATION_ADDRESS: from_user = None from_address = ITB_FOUNDATION_ADDRESS from_privkey = ITB_FOUNDATION_PRIVKEY else: from_user = User.get_user_from_eth_address( self._db_context, requests[0].from_address) from_address = from_user.eth_address from_privkey = from_user.eth_privkey # 送金先ユーザーを取得する to_user = User.get_user_from_eth_address( self._db_context, requests[0].to_address) # 送金額を集計する total_amount = sum(map(lambda x: x.amount, requests)) # 送金する wc = WalletController(from_address, from_privkey) is_success, tx_hash, error_reason = wc.send_to( requests[0].to_address, requests[0].symbol, total_amount) # 送金結果を反映する for request in requests: request.is_success = is_success request.tx_hash = tx_hash request.error_reason = error_reason request.updated_at = func.now() self._db_context.session.commit() # 送金結果を通知する if requests[0].purpose == "ガス代補充": pass elif requests[0].purpose == "新規登録ボーナス": # 送金先ユーザーに通知する if to_user.notification_enabled: channel_id = self._slackclient.open_dm_channel( to_user.slack_uid) if requests[0].is_success == True: self._slackclient.send_message( channel_id, str("新規登録ボーナスを獲得しました:laughing: (+{:.0f} ITB)\n" + "https://ropsten.etherscan.io/tx/{}"). format(total_amount, requests[0].tx_hash)) else: self._slackclient.send_message( channel_id, str("新規登録ボーナスの獲得に失敗しました:sob:\n" + "{}").format( requests[0].error_reason)) elif requests[0].purpose == "いいね!チップ": # 送金先ユーザーに通知する if to_user.notification_enabled: channel_id = self._slackclient.open_dm_channel( to_user.slack_uid) if requests[0].is_success == True: self._slackclient.send_message( channel_id, str("いいね!チップを獲得しました:laughing: (+{:.0f} ITB)\n" + "https://ropsten.etherscan.io/tx/{}"). format(total_amount, requests[0].tx_hash)) # 送金元ユーザーに通知する if from_user.notification_enabled: channel_id = self._slackclient.open_dm_channel( from_user.slack_uid) if requests[0].is_success == True: self._slackclient.send_message( channel_id, str("いいね!チップを送信しました:laughing: (-{:.0f} ITB)\n" + "https://ropsten.etherscan.io/tx/{}"). format(total_amount, requests[0].tx_hash)) else: self._slackclient.send_message( channel_id, str("いいね!チップの送信に失敗しました:sob:\n" + "{}").format( requests[0].error_reason)) elif requests[0].purpose == "グッドコミュニケーションボーナス": # 送金先ユーザーに通知する if to_user.notification_enabled: channel_id = self._slackclient.open_dm_channel( to_user.slack_uid) if requests[0].is_success == True: self._slackclient.send_message( channel_id, str("グッドコミュニケーションボーナスを獲得しました:laughing: (+{:.0f} ITB)\n" + "https://ropsten.etherscan.io/tx/{}"). format(total_amount, requests[0].tx_hash)) past_time = time.time() - start_time if past_time < self._withdrawal_interval: time.sleep(self._withdrawal_interval - past_time) def request_stop(self): """ スレッドの停止をリクエストします。 """ self._should_stop = True