예제 #1
0
def send_alert(data):
    if config.send_telegram_alerts:
        tg_bot = Bot(token=config.tg_token)
        try:
            tg_bot.sendMessage(data['telegram'],
                               data['msg'].encode('latin-1', 'backslashreplace').decode('unicode_escape'),
                               parse_mode='MARKDOWN')
        except KeyError:
            tg_bot.sendMessage(config.channel,
                               data['msg'].encode('latin-1', 'backslashreplace').decode('unicode_escape'),
                               parse_mode='MARKDOWN')
        except Exception as e:
            print('[X] Telegram Error:\n>', e)

    if config.send_discord_alerts:
        try:
            webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + data['discord'])
            embed = DiscordEmbed(title=data['msg'])
            webhook.add_embed(embed)
            response = webhook.execute()
        except KeyError:
            webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" + config.discord_webhook)
            embed = DiscordEmbed(title=data['msg'])
            webhook.add_embed(embed)
            response = webhook.execute()
        except Exception as e:
            print('[X] Discord Error:\n>', e)

    if config.send_slack_alerts:
        try:
            slack = Slack(url='https://hooks.slack.com/services/' + data['slack'])
            slack.post(text=data['msg'])
        except KeyError:
            slack = Slack(url='https://hooks.slack.com/services/' + config.slack_webhook)
            slack.post(text=data['msg'])
        except Exception as e:
            print('[X] Slack Error:\n>', e)

    if config.send_twitter_alerts:
        tw_auth = tweepy.OAuthHandler(config.tw_ckey, config.tw_csecret)
        tw_auth.set_access_token(config.tw_atoken, config.tw_asecret)
        tw_api = tweepy.API(tw_auth)
        try:
            tw_api.update_status(status=data['msg'].replace('*', '').replace('_', '').replace('`', ''))
        except Exception as e:
            print('[X] Twitter Error:\n>', e)

    if config.send_email_alerts:
        try:
            email_msg = MIMEText(data['msg'].replace('*', '').replace('_', '').replace('`', ''))
            email_msg['Subject'] = config.email_subject
            email_msg['From'] = config.email_sender
            email_msg['To'] = config.email_sender
            context = ssl.create_default_context()
            with smtplib.SMTP_SSL(config.email_host, config.email_port, context=context) as server:
                server.login(config.email_user, config.email_password)
                server.sendmail(config.email_sender, config.email_receivers, email_msg.as_string())
                server.quit()
        except Exception as e:
            print('[X] Email Error:\n>', e)
예제 #2
0
def send_slack_notification(channel, channel_url, game, live_started_at,
                            thumbnail_url, title, viewers):
    slack = Slack(url=config['webhook-url'].format(os.getenv('SLACK_API_KEY')))
    slack.post(
        text='{} is live: {}'.format(channel, game),
        blocks=[{
            'type': 'section',
            'text': {
                'type': 'mrkdwn',
                'text': '*{} is live: {}*'.format(channel, game)
            }
        }, {
            'type': 'section',
            'text': {
                'type':
                'mrkdwn',
                'text':
                '<{url}|{channel}: {title}>\n{channel} now streaming "{game} - {title}" with {viewers} viewers ({time})'
                .format(url=channel_url,
                        channel=channel,
                        title=title,
                        viewers=viewers,
                        game=game,
                        time=utc_to_local(live_started_at).strftime(
                            '%d %b %Y at %H:%M'))
            },
            'accessory': {
                'type': 'image',
                'image_url': thumbnail_url,
                'alt_text': 'Twitch thumbnail'
            }
        }])
예제 #3
0
def backup_not_found():
    ls = subprocess.Popen(['ls', '-lt', path],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          text=True)
    head = subprocess.Popen(['head', '-11'],
                            stdin=ls.stdout,
                            stdout=subprocess.PIPE,
                            text=True)
    tail = subprocess.Popen(['tail', '-10'],
                            stdin=head.stdout,
                            stdout=subprocess.PIPE,
                            text=True)
    res = tail.communicate()

    message = """
    Pi-Hole backup FAILED! Backup file not present.  The 10 most recent files are thus:

    ```{}```

    manual investigation is necessary.
    """.format(res[0])

    slack = Slack(url=webhook)
    slack.post(text=message)
예제 #4
0
    def playbook_on_stats(self, stats):
        if stats.failures:
            message = "Failure"
            color = 'danger'
        else:
            message = "Success"
            color = 'good'

        execution_time = time.time()-self.start_time

        slack = Slack(url=webhook_url)
        message = "{}@{}\nPlaybook: {}".format(self.user, self.hostname, self.playbook_name)

        fields = [{
                    "title": "Start time",
                    "value": "{}".format(self.start_datetime),
                    "short": True
                },{
                    "title": "Execution time",
                    "value": "{:10.2f}s".format(execution_time),
                    "short": True
                }]
        
        for cat in ("ok","changed","unreachable","failures","skipped","rescued","ignored"):
            results = getattr(stats, cat, {})
            found = False
            if results:
                for key in getattr(stats, cat, {}).keys():
                    found = True
                    fields.append(
                        {
                            "title": cat.capitalize(),
                            "value": "{}".format(getattr(stats, cat, {}).get(key)),
                            "short": True
                        }
                    )
            if not found:
                fields.append(
                    {
                        "title": cat.capitalize(),
                        "value": "0",
                        "short": True
                    }
                )

        self._display.warning(stats.__dict__)
        payload = [{
            "fallback": "Ansible Play Recap for {}".format(self.playbook_name),
            "color": str(color),
            "title": "Ansible Play Recap : {}".format(self.playbook_name),
            "text": str(message),
            "fields": fields
        }]

        slack.post(attachments=payload)
def sendMessage(message):
    slack = Slack(url='https://hooks.slack.com/services/###')  # Slack webhook
    slack.post(
               attachments=[{
                   "color": "#ff0000",
                   #"fallback": "Plan a vacation",
                   "author_name": "",
                   "title": "Speedtest",
                   "text": message
               }]
               )
예제 #6
0
def main():
    quotes = download_quotes(target_url)
    quotes = remove_markdown_heading_spaces(quotes)
    quote = pick_quote_for_today(quotes)

    print("Quote of the day")
    print(quote)

    if slack_webhook_url is not None:
        slack = Slack(url=slack_webhook_url)
        slack.post(text=quote)
예제 #7
0
def handle(event, context):

    # Make sure to create the secrets below
    webhook_url = fetch_secret("slack-webhook-url")
    stripe.api_key = fetch_secret("stripe-secret-key")
    webhook_secret = fetch_secret("webhook-secret")
    
    payload = event.body
    received_sig = event.headers.get("Stripe-Signature", None)
    
    try:
        event = stripe.Webhook.construct_event(
            payload, received_sig, webhook_secret
        )
    except ValueError:
        print("Error while decoding event!")
        return {
            "body": "Bad payload",
            "statusCode": 400
        }
    except stripe.error.SignatureVerificationError:
        print("Invalid signature!")
        return {
            "body": "Bad signature", 
            "statusCode": 400
        }

    # Fail for all other event types  
    if event.type != "charge.succeeded":
        return {
            "body":"Unsupported event type",
            "statusCode": 422
        }
  
    amount = numbers.format_currency(
      event.data.object.amount / 100,
      event.data.object.currency.upper(), 
      locale='en'
    )

    try:
        slack = Slack(url=webhook_url)
        slack.post(text=f"You have a received a new payment of {amount} :moneybag: :tada:")
    except:
        print("An error occured when trying to send slack message.")
        return {
            "body": "Could not send slack message", 
            "statusCode": 500
        }
    return {
        "body": "Notification was sent successfully to Slack", 
        "statusCode": 200
    }
예제 #8
0
 def sendSlack(self):
     self.set_globalSettings(self.defaultSettings, "SlackWebHook")
     if len(self.globalSettings.get("SlackWebHook")) > 0:
         lis = self.get_list(self.globalSettings.get("SlackWebHook"))
         try:
             for hooks in lis:
                 text = self.subject+"\n\n"+self.body
                 slack = Slack(url=hooks)
                 slack.post(text=text)
                 logger.info(f"Slack sent to: {hooks}")
         except Exception as ex:
             logger.info(ex)
예제 #9
0
def crawling():
    with open('config.json', 'r') as f:
        config = json.load(f)

    time.sleep(random.choice(r_times))

    html = requests.get(
        web_url,
        headers={
            'User-Agent':
            'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36'
        }).text
    soup = BeautifulSoup(html, 'html.parser')

    result_text = soup.text[6:-2]
    a = json.loads(result_text)
    postList = a['result']['popularPostBlockInfoList'][0]['postList']

    now = datetime.datetime.now()
    month = int(now.strftime('%m'))
    nowDate = now.strftime(
        (str(month) + '월%d일'
         ).encode('unicode-escape').decode()).encode().decode('unicode-escape')

    for post in postList:
        if nowDate in post['titleWithInspectMessage']:
            img_src = post['thumbnailList'][0]['encodedThumbnailUrl']
            slack = Slack(url=config['WEBHOOK_URL'])

            today_menu = "쉐프스케치, " + "[" + nowDate + "] 오늘의 메뉴"
            slack.post(
                text=today_menu,
                channel="#오늘의메뉴",
                attachments=[{
                    # "fallback": href,
                    # "pretext": href,
                    "color": "#00FFFF",
                    "author_name": "",
                    "title": today_menu,
                    # "title_link": href,
                    "image_url": img_src,
                    "thumb_url": img_src,
                    # "actions": [
                    #     {
                    #         "name": "action",
                    #         "type": "button",
                    #         "text": "Complete this task",
                    #         "style": "",
                    #         "value": "complete"
                    #     },
                    # ]
                }])
예제 #10
0
 def send(self):
     webhook_url = self.get_destination()
     payload = self.get_messages()
     slack = Slack(url=webhook_url)
     if 'text' not in payload.keys():
         expression = payload
         messages = 'text key not exist on payload input'
         raise InputExpression(expression, messages)
     elif 'attachments' not in payload.keys():
         slack.post(text=payload['text'])
     else:
         slack.post(text=payload['text'],
                    attachments=payload['attachments'])
예제 #11
0
def success(message):
    slack = Slack(url=SLACK_WEBHOOK)
    slack.post(text=KST.strftime('%Y.%m.%d') + " 자가진단 결과: ✅ 성공",
               attachments=[{
                   "color":
                   "#00b894",
                   "author_name":
                   "✅ " + KST.strftime('%Y.%m.%d'),
                   "title":
                   message,
                   "text":
                   "처리 기준 (KST): " + KST.strftime('%Y-%m-%d %H:%M:%S')
               }])
예제 #12
0
def failed(message):
    slack = Slack(url=SLACK_WEBHOOK)
    slack.post(text=KST.strftime('%Y.%m.%d') + " 자가진단 결과: ⛔️ 실패",
               attachments=[{
                   "color":
                   "#d63031",
                   "author_name":
                   "⛔ " + KST.strftime('%Y.%m.%d'),
                   "title":
                   message,
                   "text":
                   "처리 기준 (KST): " + KST.strftime('%Y-%m-%d %H:%M:%S')
               }])
예제 #13
0
def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    slack_url = os.getenv('SLACK_URL')
    slack = Slack(url=(slack_url))
    req_body = req.get_json()
    logging.info(format(req_body))
    slack.post(text=f"system: {req_body['systemName']} \n"
               f"system model: {req_body['systemModel']} \n"
               f"current score: {req_body['currentScore']} \n"
               f"timestamp: {req_body['timestampIso8601']} \n"
               "description: {req_body['description']} \n"
               "resolution: {req_body['resolution']}")
    #    slack.post(text=f"system: {req_body}")
    logging.info('Successfully posted to Slack.')
    return func.HttpResponse(format(req_body))
 def publish_cluster():
   slack= Slack(url='https://hooks.slack.com/services/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')
   credentials = key_read(file_loc)
   # Code for Redshift Task
   try:
     session = boto3.Session(
              aws_access_key_id=credentials['access_key'] ,
              aws_secret_access_key=credentials['secret_key'],
              aws_session_token=credentials['token']
              )
     ddb = session.client('redshift', 'us-east-1')
     cluster_list = ddb.describe_clusters()
     slack.post(text="Describe Clusters Detail Successful") 
   except:
     slack.post("Invalid Credentials or EC2 Role")
예제 #15
0
def send_slack_webhook_message(match, videogoal, videogoal_mirror,
                               event_filter):
    try:
        webhooks = Webhook.objects.filter(
            destination__exact=Webhook.WebhookDestinations.Slack,
            event_type=event_filter)
        print(
            f"WEBHOOK - Checking {str(event_filter)} - {str(len(webhooks))} SLACK WEBHOOKS",
            flush=True)
        for wh in webhooks:
            to_send = check_conditions(match, wh) and \
                      check_link_regex(wh, videogoal, videogoal_mirror, event_filter) and \
                      check_author(wh, videogoal, videogoal_mirror, event_filter)
            if not to_send:
                continue
            message = format_event_message(match, videogoal, videogoal_mirror,
                                           wh.message)
            try:
                slack = Slack(url=wh.webhook_url)
                response = slack.post(text=message)
                print(response, flush=True)
            except Exception as ex:
                print("Error sending webhook single message: " + str(ex),
                      flush=True)
    except Exception as ex:
        print("Error sending webhook messages: " + str(ex), flush=True)
예제 #16
0
def nfs_not_mounted():
    # print('NFS not mounted')
    cmd = ['df', '-h']
    res = subprocess.run(cmd, capture_output=True, text=True)

    message = """
    Pi-Hole backup FAILED! Backup directory not present.

    the following is the output of `df -h`:

    ```{}```

    manual investigation is necessary.
    """.format(res.stdout)

    slack = Slack(url=webhook)
    slack.post(text=message)
예제 #17
0
def sendSlackNotify(event: eventData.ContEvent, data: dataData.ContData, config: configInit.Config):
    slackClient = Slack(url=config.slackUrl)

    imageIcon = logoIcons.getLogoUrl(event.image)
    mainInfo = f"_Docker Container Crashed Detected_\n\n:pirate_flag: *Container Name*\n `{event.name.capitalize()}`\n\n"
    introMsg = sectionWithImage(mainInfo, imageIcon)

    errorMsg = newSection(f"{data.errorMsg}\n")

    tagsField = None
    if config.tags is not None:
        tags = ""
        for t in config.tags:
            tags = tags + f"`{t}`; "

        tagsField = f":flags: *Tags*\n{tags}\n\n"
        tagsField = newSection(tagsField)

    restartPolicy = None
    if data.restartPolicy is not None:
        restartPolicy = f":repeat: *Restart Policy*: `{data.restartPolicy}`\n:repeat_one: *Max Count Restarts Notify*: `{config.restartPolicyCountNotify}`\n"
        restartPolicy = restartPolicy + f":arrows_counterclockwise: *Current Restart Count*: `{data.restartCount}`\n\n"
        restartPolicy = newSection(restartPolicy)

    image = f":frame_with_picture: *Image*\n`{event.image}`\n\n"
    image = newSection(image)

    exitCode = f":small_orange_diamond: *Exit Code*\n `{data.exitCode}`\n\n"
    exitCode = newSection(exitCode)

    oomKilled = f":anger: OOMKilled\n`{data.oomKilled}`\n\n"
    oomKilled = newSection(oomKilled)

    allFields = [introMsg, errorMsg, divider(), tagsField, restartPolicy, image, exitCode, oomKilled]

    filteredFields = [i for i in allFields if i]

    try:
        slackClient.post(blocks=filteredFields)
    except Exception as e:
        print(f"ERROR while sending message to Slack. Please check if the webhook URL is valid - now exiting! {e}")
        sys.exit(0)
예제 #18
0
파일: app.py 프로젝트: basketgate/api
    def post(self):
        # Get name and email to send Slack

        logging.error("Send Slack Root")

        json_input = request.get_json()
        user_name_raw = json_input['user_name']
        logging.error("raw : " + user_name_raw)
        user_email_raw = json_input['user_email']
        logging.error("raw : " + user_email_raw)

        slack = Slack(
            url=f'https://hooks.slack.com/services/{config.slack_key}')
        slack.post(
            text=
            f"User : {user_name_raw} , email : {user_email_raw} have requested a demo"
        )

        # return OK
        return "OK"
예제 #19
0
async def scale_up(request):
	global TOKEN
	global RANCHER_VM_MAX
	
	#authentication of requester to autoscaler
	if request.match_dict['token'] != TOKEN:
		print(f"token '{request.match_dict['token']}' not valid\n")
		return request.Response(text='ok')

	#authentication with Rancher
	pool = await get_nodepool()

	# check if we have uncordoned a node
	uncordoned_node, message = await try_uncordon_node_of_nodepool(pool['links']['nodes'])
	print(f"{message}")
	slack = Slack(url=SLACK_URL)
	if uncordoned_node:
		print(f"Not scaling up, Waiting for next message...\n")
		slack.post(text="Autoscaler message: "+message+ "\nNot scaling up, Waiting for next message...")
		return request.Response(text='ok')
	
	old = pool['quantity']
	pool['quantity'] = pool['quantity'] + 1
	# limit maximum VMs
	if RANCHER_VM_MAX + 1 <= pool['quantity']:
		print(f"Not scaling up, at maximum number of nodes\n")
		slack.post(text="Autoscaler message: "+message+ "\nNot scaling up, at maximum number of nodes")
		return request.Response(text='ok')

	slack.post(text="Autoscaler message: "+message)
	print(f"scale up {old} --> {pool['quantity']}")
	await set_nodepool(pool)
	return request.Response(text='ok')
예제 #20
0
async def scale_down(request):
	#authentication of requester to autoscaler
	global TOKEN
	if request.match_dict['token'] != TOKEN:
		print(f"token '{request.match_dict['token']}' not valid\n")
		return request.Response(text='ok')
	
	#authentication with Rancher
	pool = await get_nodepool()

	#setup slack webhook
	slack = Slack(url=SLACK_URL)

	#if we have reached the minimum number of nodes possible, end request
	if pool['quantity'] <= RANCHER_VM_MIN:
		print(f'quantity <= {RANCHER_VM_MIN}\n')
		slack.post(text="Autoscaler message: Not scaling down, quantity <= "+str(RANCHER_VM_MIN))
		return request.Response(text='ok')

	# check if we have Cordoned node
	cordoned_node, message = await try_cordon_last_node_of_nodepool(pool['links']['nodes'], pool['hostnamePrefix'])
	print(f"{message}")
	if cordoned_node:
		print(f"Not scaling down, cordoning node instead. Waiting for next message...\n")
		slack.post(text="Autoscaler message: "+message+ "\nNot scaling down, Waiting for next message...")
		return request.Response(text='ok')

	#if we have reached here, scale down the node pool
	old = pool['quantity']
	pool['quantity'] = pool['quantity'] - 1
	print(f"scale down {old} --> {pool['quantity']}")
	slack.post(text="Autoscaler message: "+message+ "\nscale down "+str(old)+" --> "+str(pool['quantity']))
	await set_nodepool(pool)
	return request.Response(text='ok')
예제 #21
0
def backup_found():
    ls = subprocess.Popen(['ls', '-lt', path],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          text=True)
    head = subprocess.Popen(['head', '-2'],
                            stdin=ls.stdout,
                            stdout=subprocess.PIPE,
                            text=True)
    tail = subprocess.Popen(['tail', '-1'],
                            stdin=head.stdout,
                            stdout=subprocess.PIPE,
                            text=True)
    res = tail.communicate()

    message = """
    Pi-Hole backup SUCCEEDED! Backup file created.  The most recent file is: ```{}```
    Qapla'!
    """.format(res[0])

    slack = Slack(url=webhook)
    slack.post(text=message)
def lambda_handler(event, context):
    print('add current working directory to PATH')
    slack = Slack(url=os.environ['SLACK_WEBHOOK_URL'])
    os.environ['PATH'] = os.environ['PATH'] + ':' + os.path.dirname(
        os.path.abspath(__file__)) + ':' + os.path.join(
            os.path.dirname(os.path.abspath(__file__)), 'bin')
    try:
        mp3file_name = download()
        upload_to_s3(mp3file_name, os.environ['UPLOAD_GOOGLE_DRIVE_DIRECTORY'])
        upload_to_google_drive(mp3file_name,
                               os.environ['UPLOAD_GOOGLE_DRIVE_DIRECTORY'])
        upload_to_youtube_music(mp3file_name)
        slack.post(text='[insideout] :tada: done recording insideout')
    except Exception as e:
        slack.post(text='[insideout] :red_circle: failed to record insideout')
        raise e

    # run radirec
    return {
        'isBase64Encoded': False,
        'statusCode': 200,
        'headers': {},
        'body': '{"message": "Hello from AWS Lambda"}'
    }
예제 #23
0
def send_slack_webhook_message(match, videogoal, videogoal_mirror,
                               event_filter):
    try:
        webhooks = Webhook.objects.filter(
            destination__exact=Webhook.WebhookDestinations.Slack,
            event_type=event_filter)
        for wh in webhooks:
            to_send = check_conditions(match, wh) and \
                      check_link_regex(wh, videogoal, videogoal_mirror, event_filter) and \
                      check_author(wh, videogoal, videogoal_mirror, event_filter)
            if not to_send:
                return
            message = format_event_message(match, videogoal, videogoal_mirror,
                                           wh.message)
            try:
                slack = Slack(url=wh.webhook_url)
                response = slack.post(text=message)
                print(response)
            except Exception as ex:
                print("Error sending webhook single message: " + str(ex))
    except Exception as ex:
        print("Error sending webhook messages: " + str(ex))
예제 #24
0
def send_message(sender, instance, **kwargs):
    if kwargs['action'] != 'post_add':
        return
    result = ''
    for wh in instance.webhooks.all():
        if wh.destination == Webhook.WebhookDestinations.Discord:
            try:
                webhook = DiscordWebhook(url=wh.webhook_url, content=instance.message)
                response = webhook.execute()
                result += wh.title + "\n" + str(response.content) + "\n\n"
                print(response.content, flush=True)
            except Exception as ex:
                print("Error sending webhook single message: " + str(ex), flush=True)
                result += wh.title + "\n" + str(ex) + "\n\n"
        elif wh.destination == Webhook.WebhookDestinations.Slack:
            try:
                slack = Slack(url=wh.webhook_url)
                response = slack.post(text=instance.message)
                print(response, flush=True)
                result += wh.title + "\n" + str(response) + "\n\n"
            except Exception as ex:
                print("Error sending webhook single message: " + str(ex), flush=True)
                result += wh.title + "\n" + str(ex) + "\n\n"
    CustomMessage.objects.filter(id=instance.id).update(result=result)
예제 #25
0
def notify_slack(post):
    slack = Slack(url=os.environ.get('SLACK_URL'))
    slack.post(text=post)
예제 #26
0
        #draw.text((x, top+25), str(Disk),  font=font, fill=255)

        # Display image.
        disp.image(image)
        disp.display()
        #time.sleep(.1)

    # if it is later in the day and temperature outside is less than
    # inside temperature open the window

    # check operating window - this sets time constraints
    if (outTemp >= inTemp):
        if (notFlagged is True):
            notFlagged = False
            try:
                slack.post(text=str(weather['time']) + " " + tempStr +
                           " Outside temp greater than inside")
            except Exception as e:
                print("Error on slack post")
    else:
        if (outTemp < inTemp - 1.0):  # stop the ping pong
            notFlagged = True

    # we need the outside temperature to be pleasant and for it
    # to be a degree or two lower that the inside temperature
    # and for the inside temperature not to drop below 22
    #
    # - add some hysteresis so it doesn't go up and down! - add timer
    # - have been agreessive on the 'differences' as the outside read
    #  is a bit high
    timeDelay = 30 * 60  # 30mins
예제 #27
0
def send_alert(data):
    msg = data["msg"].encode("latin-1",
                             "backslashreplace").decode("unicode_escape")
    if config.send_telegram_alerts:
        tg_bot = Bot(token=config.tg_token)
        try:
            tg_bot.sendMessage(
                data["telegram"],
                msg,
                parse_mode="MARKDOWN",
            )
        except KeyError:
            tg_bot.sendMessage(
                config.channel,
                msg,
                parse_mode="MARKDOWN",
            )
        except Exception as e:
            print("[X] Telegram Error:\n>", e)

    if config.send_discord_alerts:
        try:
            webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" +
                                     data["discord"])
            embed = DiscordEmbed(title=msg)
            webhook.add_embed(embed)
            webhook.execute()
        except KeyError:
            webhook = DiscordWebhook(url="https://discord.com/api/webhooks/" +
                                     config.discord_webhook)
            embed = DiscordEmbed(title=msg)
            webhook.add_embed(embed)
            webhook.execute()
        except Exception as e:
            print("[X] Discord Error:\n>", e)

    if config.send_slack_alerts:
        try:
            slack = Slack(url="https://hooks.slack.com/services/" +
                          data["slack"])
            slack.post(text=msg)
        except KeyError:
            slack = Slack(url="https://hooks.slack.com/services/" +
                          config.slack_webhook)
            slack.post(text=msg)
        except Exception as e:
            print("[X] Slack Error:\n>", e)

    if config.send_twitter_alerts:
        tw_auth = tweepy.OAuthHandler(config.tw_ckey, config.tw_csecret)
        tw_auth.set_access_token(config.tw_atoken, config.tw_asecret)
        tw_api = tweepy.API(tw_auth)
        try:
            tw_api.update_status(
                status=msg.replace("*", "").replace("_", "").replace("`", ""))
        except Exception as e:
            print("[X] Twitter Error:\n>", e)

    if config.send_email_alerts:
        try:
            email_msg = MIMEText(
                msg.replace("*", "").replace("_", "").replace("`", ""))
            email_msg["Subject"] = config.email_subject
            email_msg["From"] = config.email_sender
            email_msg["To"] = config.email_sender
            context = ssl.create_default_context()
            with smtplib.SMTP_SSL(config.email_host,
                                  config.email_port,
                                  context=context) as server:
                server.login(config.email_user, config.email_password)
                server.sendmail(config.email_sender, config.email_receivers,
                                email_msg.as_string())
                server.quit()
        except Exception as e:
            print("[X] Email Error:\n>", e)
예제 #28
0
def send_to_slack(title, url, chapter):
    webhook_url = WEBHOOK_URL  # 公開するな!
    slack = Slack(url=webhook_url)
    message = f'【更新】: {title}  {chapter} \n{url}'
    slack.post(text=message)
예제 #29
0
class Bot(object):
    WINTER_TIME = 21
    SUMMER_TIME = 20

    def __init__(
        self,
        *,
        account_id: str,
        access_token: str,
        environment: str = "practice",
        instrument: str = "EUR_USD",
        granularity: str = "D",
        trading_time: int = SUMMER_TIME,
        slack_webhook_url: str = "",
        discord_webhook_url: str = "",
        line_notify_token: str = "",
    ) -> None:
        self.BUY = 1
        self.SELL = -1
        self.EXIT = False
        self.ENTRY = True
        self.trading_time = trading_time
        self.account_id = account_id
        self.headers = {
            "Content-Type": "application/json",
            "Authorization": "Bearer {}".format(access_token),
        }
        if environment == "practice":
            self.base_url = "https://api-fxpractice.oanda.com"
        else:
            self.base_url = "https://api-fxtrade.oanda.com"
        self.sched = BlockingScheduler()
        self.instrument = instrument
        self.granularity = granularity
        if len(granularity) > 1:
            if granularity[0] == "S":
                self.sched.add_job(self._job, "cron", second="*/" + granularity[1:])
            elif granularity[0] == "M":
                self.sched.add_job(self._job, "cron", minute="*/" + granularity[1:])
            elif granularity[0] == "H":
                self.sched.add_job(self._job, "cron", hour="*/" + granularity[1:])
        else:
            if granularity == "D":
                self.sched.add_job(self._job, "cron", day="*")
            elif granularity == "W":
                self.sched.add_job(self._job, "cron", week="*")
            elif granularity == "M":
                self.sched.add_job(self._job, "cron", month="*")
        if slack_webhook_url == "":
            self.slack = None
        else:
            self.slack = Slack(url=slack_webhook_url)
        if line_notify_token == "":
            self.line = None
        else:
            self.line = Line(token=line_notify_token)
        if discord_webhook_url == "":
            self.discord = None
        else:
            self.discord = Discord(url=discord_webhook_url)
        formatter = logging.Formatter(
            "%(asctime)s - %(funcName)s - %(levelname)s - %(message)s"
        )
        handler = logging.StreamHandler()
        handler.setLevel(logging.INFO)
        handler.setFormatter(formatter)
        self.log = logging.getLogger(__name__)
        self.log.setLevel(logging.INFO)
        self.log.addHandler(handler)
        if "JPY" in self.instrument:
            self.point = 0.01
        else:
            self.point = 0.0001
        self.units = 10000  # currency unit
        self.take_profit = 0
        self.stop_loss = 0
        self.buy_entry = (
            self.buy_exit
        ) = self.sell_entry = self.sell_exit = pd.DataFrame()

    def _candles(
        self, *, from_date: str = "", to_date: str = "", count: str = "5000"
    ) -> pd.DataFrame:
        url = "{}/v3/instruments/{}/candles".format(self.base_url, self.instrument)
        params = {"granularity": self.granularity, "count": count}
        if from_date != "":
            _dt = dateutil.parser.parse(from_date)
            params["from"] = str(
                datetime.datetime(
                    _dt.year, _dt.month, _dt.day, tzinfo=datetime.timezone.utc
                ).date()
            )
        if to_date != "":
            _dt = dateutil.parser.parse(to_date)
            params["to"] = str(
                datetime.datetime(
                    _dt.year, _dt.month, _dt.day, tzinfo=datetime.timezone.utc
                ).date()
            )
        data = []
        if "from" in params and "to" in params:
            _from = params["from"]
            _to = params["to"]
            del params["to"]
            while _to > _from:
                time.sleep(0.5)
                params["from"] = _from
                res = requests.get(url, headers=self.headers, params=params)
                if res.status_code != 200:
                    self._error(
                        "status_code {} - {}".format(res.status_code, res.json())
                    )
                for r in res.json()["candles"]:
                    data.append(
                        [
                            pd.to_datetime(r["time"]),
                            float(r["mid"]["o"]),
                            float(r["mid"]["h"]),
                            float(r["mid"]["l"]),
                            float(r["mid"]["c"]),
                            float(r["volume"]),
                        ]
                    )
                _dt = pd.to_datetime(res.json()["candles"][-1]["time"])
                _from = str(datetime.date(_dt.year, _dt.month, _dt.day))
        else:
            res = requests.get(url, headers=self.headers, params=params)
            if res.status_code != 200:
                self._error("status_code {} - {}".format(res.status_code, res.json()))
            for r in res.json()["candles"]:
                data.append(
                    [
                        pd.to_datetime(r["time"]),
                        float(r["mid"]["o"]),
                        float(r["mid"]["h"]),
                        float(r["mid"]["l"]),
                        float(r["mid"]["c"]),
                        float(r["volume"]),
                    ]
                )
        self.df = (
            pd.DataFrame(data, columns=["T", "O", "H", "L", "C", "V"])
            .set_index("T")
            .drop_duplicates()
        )
        return self.df

    def __accounts(self) -> requests.models.Response:
        url = "{}/v3/accounts/{}".format(self.base_url, self.account_id)
        res = requests.get(url, headers=self.headers)
        if res.status_code != 200:
            self._error("status_code {} - {}".format(res.status_code, res.json()))
        return res

    def _account(self) -> Tuple[bool, bool]:
        buy_position = False
        sell_position = False
        for pos in self.__accounts().json()["account"]["positions"]:
            if pos["instrument"] == self.instrument:
                if pos["long"]["units"] != "0":
                    buy_position = True
                if pos["short"]["units"] != "0":
                    sell_position = True
        return buy_position, sell_position

    def __order(self, data: Any) -> requests.models.Response:
        url = "{}/v3/accounts/{}/orders".format(self.base_url, self.account_id)
        res = requests.post(url, headers=self.headers, data=json.dumps(data))
        if res.status_code != 201:
            self._error("status_code {} - {}".format(res.status_code, res.json()))
        return res

    def _order(self, sign: int, entry: bool = False) -> None:
        order = {}
        order["instrument"] = self.instrument
        order["units"] = str(self.units * sign)
        order["type"] = "MARKET"
        order["positionFill"] = "DEFAULT"
        res = self.__order({"order": order})
        order_id = res.json()["orderFillTransaction"]["id"]
        price = float(res.json()["orderFillTransaction"]["price"])
        if self.stop_loss != 0 and entry:
            stop_loss = {}
            stop_loss["timeInForce"] = "GTC"
            stop_loss["price"] = str(
                round(price + (self.stop_loss * self.point * -sign), 3)
            )
            stop_loss["type"] = "STOP_LOSS"
            stop_loss["tradeID"] = order_id
            self.__order({"order": stop_loss})
        if self.take_profit != 0 and entry:
            take_profit = {}
            take_profit["timeInForce"] = "GTC"
            take_profit["price"] = str(
                round(price + (self.take_profit * self.point * sign), 3)
            )
            take_profit["type"] = "TAKE_PROFIT"
            take_profit["tradeID"] = order_id
            self.__order({"order": take_profit})

    def _is_close(self) -> bool:
        utcnow = datetime.datetime.utcnow()
        hour = utcnow.hour
        weekday = utcnow.weekday()
        if (
            (4 == weekday and self.trading_time < hour)
            or 5 == weekday
            or (6 == weekday and self.trading_time >= hour)
        ):
            return True
        return False

    def _job(self) -> None:
        if self._is_close():
            return None
        self._candles(count="500")
        self.strategy()
        buy_position, sell_position = self._account()
        buy_entry = self.buy_entry[-1]
        sell_entry = self.sell_entry[-1]
        buy_exit = self.buy_exit[-1]
        sell_exit = self.sell_exit[-1]
        # buy entry
        if buy_entry and not buy_position:
            if sell_position:
                self._order(self.BUY)
            self._order(self.BUY, self.ENTRY)
            return None
        # sell entry
        if sell_entry and not sell_position:
            if buy_position:
                self._order(self.SELL)
            self._order(self.SELL, self.ENTRY)
            return None
        # buy exit
        if buy_exit and buy_position:
            self._order(self.SELL)
        # sell exit
        if sell_exit and sell_position:
            self._order(self.BUY)

    def _error(self, message: Any = {}) -> None:
        self.log.error(message)
        if self.slack is not None:
            self.slack.post(text=message)
        if self.line is not None:
            self.line.post(message=message)
        if self.discord is not None:
            self.discord.post(content=message)

    def __transactions(self, params: Any = {}) -> requests.models.Response:
        url = "{}/v3/accounts/{}/transactions".format(self.base_url, self.account_id)
        res = requests.get(url, headers=self.headers, params=params)
        if res.status_code != 200:
            self._error("status_code {} - {}".format(res.status_code, res.json()))
        return res

    def __transactions_sinceid(self, params: Any = {}) -> requests.models.Response:
        url = "{}/v3/accounts/{}/transactions/sinceid".format(
            self.base_url, self.account_id
        )
        res = requests.get(url, headers=self.headers, params=params)
        if res.status_code != 200:
            self._error("status_code {} - {}".format(res.status_code, res.json()))
        return res

    def report(self, *, days: int = -1, filename: str = "",) -> None:
        tran = self.__transactions(
            {
                "from": (
                    datetime.datetime.utcnow().date() + datetime.timedelta(days=days)
                ),
                "type": "ORDER_FILL",
            }
        ).json()
        id = parse.parse_qs(parse.urlparse(tran["pages"][0]).query)["from"]
        data = []
        for t in self.__transactions_sinceid({"id": id, "type": "ORDER_FILL"}).json()[
            "transactions"
        ]:
            if float(t["pl"]) == 0.0:
                continue
            data.append(
                [
                    pd.to_datetime(t["time"]),
                    t["id"],
                    float(t["pl"]),
                    round(float(t["pl"]), 2),
                    float(t["price"]),
                    float(t["accountBalance"]),
                ]
            )
        df = pd.DataFrame(
            data, columns=["time", "id", "pl", "rr", "price", "accountBalance"]
        ).set_index("time")

        s = pd.Series(dtype="object")
        s.loc["total profit"] = round(df["pl"].sum(), 3)
        s.loc["total trades"] = len(df["pl"])
        s.loc["win rate"] = round(len(df[df["pl"] > 0]) / len(df["pl"]) * 100, 3)
        s.loc["profit factor"] = round(
            df[df["pl"] > 0]["pl"].sum() / df[df["pl"] <= 0]["pl"].sum(), 3
        )
        s.loc["maximum drawdown"] = round(
            (df["accountBalance"].cummax() - df["accountBalance"]).max(), 3
        )
        s.loc["recovery factor"] = round(
            df["pl"].sum()
            / (df["accountBalance"].cummax() - df["accountBalance"]).max(),
            3,
        )
        s.loc["riskreward ratio"] = round(
            (df[df["pl"] > 0]["pl"].sum() / len(df[df["pl"] > 0]))
            / (df[df["pl"] <= 0]["pl"].sum() / len(df[df["pl"] <= 0])),
            3,
        )
        s.loc["sharpe ratio"] = round(df["rr"].mean() / df["rr"].std(), 3)
        s.loc["average return"] = round(df["rr"].mean(), 3)
        print(s)

        fig = plt.figure()
        fig.subplots_adjust(
            wspace=0.2, hspace=0.7, left=0.095, right=0.95, bottom=0.095, top=0.95
        )
        ax1 = fig.add_subplot(3, 1, 1)
        ax1.plot(df["price"], label="price")
        ax1.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d\n%H:%M"))
        ax1.legend()
        ax2 = fig.add_subplot(3, 1, 2)
        ax2.plot(df["accountBalance"], label="accountBalance")
        ax2.xaxis.set_major_formatter(mdates.DateFormatter("%m-%d\n%H:%M"))
        ax2.legend()
        ax3 = fig.add_subplot(3, 1, 3)
        ax3.hist(df["rr"], 50, rwidth=0.9)
        ax3.axvline(
            df["rr"].mean(), color="orange", label="average return",
        )
        ax3.legend()
        if filename == "":
            plt.show()
        else:
            plt.savefig(filename)

    def strategy(self) -> None:
        pass

    def backtest(
        self, *, from_date: str = "", to_date: str = "", filename: str = ""
    ) -> None:
        csv = "{}-{}-{}-{}.csv".format(
            self.instrument, self.granularity, from_date, to_date
        )
        if os.path.exists(csv):
            self.df = pd.read_csv(
                csv, index_col=0, parse_dates=True, infer_datetime_format=True
            )
        else:
            self._candles(from_date=from_date, to_date=to_date)
            if from_date != "" and to_date != "":
                self.df.to_csv(csv)
        self.strategy()
        o = self.df.O.values
        L = self.df.L.values
        h = self.df.H.values
        N = len(self.df)
        long_trade = np.zeros(N)
        short_trade = np.zeros(N)

        # buy entry
        buy_entry_s = np.hstack((False, self.buy_entry[:-1]))  # shift
        long_trade[buy_entry_s] = o[buy_entry_s]
        # buy exit
        buy_exit_s = np.hstack((False, self.buy_exit[:-2], True))  # shift
        long_trade[buy_exit_s] = -o[buy_exit_s]
        # sell entry
        sell_entry_s = np.hstack((False, self.sell_entry[:-1]))  # shift
        short_trade[sell_entry_s] = o[sell_entry_s]
        # sell exit
        sell_exit_s = np.hstack((False, self.sell_exit[:-2], True))  # shift
        short_trade[sell_exit_s] = -o[sell_exit_s]

        long_pl = pd.Series(np.zeros(N))  # profit/loss of buy position
        short_pl = pd.Series(np.zeros(N))  # profit/loss of sell position
        buy_price = sell_price = 0
        long_rr = []  # long return rate
        short_rr = []  # short return rate
        stop_loss = take_profit = 0

        for i in range(1, N):
            # buy entry
            if long_trade[i] > 0:
                if buy_price == 0:
                    buy_price = long_trade[i]
                    short_trade[i] = -buy_price  # sell exit
                else:
                    long_trade[i] = 0

            # sell entry
            if short_trade[i] > 0:
                if sell_price == 0:
                    sell_price = short_trade[i]
                    long_trade[i] = -sell_price  # buy exit
                else:
                    short_trade[i] = 0

            # buy exit
            if long_trade[i] < 0:
                if buy_price != 0:
                    long_pl[i] = (
                        -(buy_price + long_trade[i]) * self.units
                    )  # profit/loss fixed
                    long_rr.append(
                        round(long_pl[i] / buy_price * 100, 2)
                    )  # long return rate
                    buy_price = 0
                else:
                    long_trade[i] = 0

            # sell exit
            if short_trade[i] < 0:
                if sell_price != 0:
                    short_pl[i] = (
                        sell_price + short_trade[i]
                    ) * self.units  # profit/loss fixed
                    short_rr.append(
                        round(short_pl[i] / sell_price * 100, 2)
                    )  # short return rate
                    sell_price = 0
                else:
                    short_trade[i] = 0

            # close buy position with stop loss
            if buy_price != 0 and self.stop_loss > 0:
                stop_price = buy_price - self.stop_loss * self.point
                if L[i] <= stop_price:
                    long_trade[i] = -stop_price
                    long_pl[i] = (
                        -(buy_price + long_trade[i]) * self.units
                    )  # profit/loss fixed
                    long_rr.append(
                        round(long_pl[i] / buy_price * 100, 2)
                    )  # long return rate
                    buy_price = 0
                    stop_loss += 1

            # close buy positon with take profit
            if buy_price != 0 and self.take_profit > 0:
                limit_price = buy_price + self.take_profit * self.point
                if h[i] >= limit_price:
                    long_trade[i] = -limit_price
                    long_pl[i] = (
                        -(buy_price + long_trade[i]) * self.units
                    )  # profit/loss fixed
                    long_rr.append(
                        round(long_pl[i] / buy_price * 100, 2)
                    )  # long return rate
                    buy_price = 0
                    take_profit += 1

            # close sell position with stop loss
            if sell_price != 0 and self.stop_loss > 0:
                stop_price = sell_price + self.stop_loss * self.point
                if h[i] >= stop_price:
                    short_trade[i] = -stop_price
                    short_pl[i] = (
                        sell_price + short_trade[i]
                    ) * self.units  # profit/loss fixed
                    short_rr.append(
                        round(short_pl[i] / sell_price * 100, 2)
                    )  # short return rate
                    sell_price = 0
                    stop_loss += 1

            # close sell position with take profit
            if sell_price != 0 and self.take_profit > 0:
                limit_price = sell_price - self.take_profit * self.point
                if L[i] <= limit_price:
                    short_trade[i] = -limit_price
                    short_pl[i] = (
                        sell_price + short_trade[i]
                    ) * self.units  # profit/loss fixed
                    short_rr.append(
                        round(short_pl[i] / sell_price * 100, 2)
                    )  # short return rate
                    sell_price = 0
                    take_profit += 1

        win_trades = np.count_nonzero(long_pl.clip(lower=0)) + np.count_nonzero(
            short_pl.clip(lower=0)
        )
        lose_trades = np.count_nonzero(long_pl.clip(upper=0)) + np.count_nonzero(
            short_pl.clip(upper=0)
        )
        trades = (np.count_nonzero(long_trade) // 2) + (
            np.count_nonzero(short_trade) // 2
        )
        gross_profit = long_pl.clip(lower=0).sum() + short_pl.clip(lower=0).sum()
        gross_loss = long_pl.clip(upper=0).sum() + short_pl.clip(upper=0).sum()
        profit_pl = gross_profit + gross_loss
        self.equity = (long_pl + short_pl).cumsum()
        mdd = (self.equity.cummax() - self.equity).max()
        self.return_rate = pd.Series(short_rr + long_rr)

        s = pd.Series(dtype="object")
        s.loc["total profit"] = round(profit_pl, 3)
        s.loc["total trades"] = trades
        s.loc["win rate"] = round(win_trades / trades * 100, 3)
        s.loc["profit factor"] = round(-gross_profit / gross_loss, 3)
        s.loc["maximum drawdown"] = round(mdd, 3)
        s.loc["recovery factor"] = round(profit_pl / mdd, 3)
        s.loc["riskreward ratio"] = round(
            -(gross_profit / win_trades) / (gross_loss / lose_trades), 3
        )
        s.loc["sharpe ratio"] = round(
            self.return_rate.mean() / self.return_rate.std(), 3
        )
        s.loc["average return"] = round(self.return_rate.mean(), 3)
        s.loc["stop loss"] = stop_loss
        s.loc["take profit"] = take_profit
        print(s)

        fig = plt.figure()
        fig.subplots_adjust(
            wspace=0.2, hspace=0.5, left=0.095, right=0.95, bottom=0.095, top=0.95
        )
        ax1 = fig.add_subplot(3, 1, 1)
        ax1.plot(self.df.C, label="close")
        ax1.legend()
        ax2 = fig.add_subplot(3, 1, 2)
        ax2.plot(self.equity, label="equity")
        ax2.legend()
        ax3 = fig.add_subplot(3, 1, 3)
        ax3.hist(self.return_rate, 50, rwidth=0.9)
        ax3.axvline(
            sum(self.return_rate) / len(self.return_rate),
            color="orange",
            label="average return",
        )
        ax3.legend()
        if filename == "":
            plt.show()
        else:
            plt.savefig(filename)

    def run(self) -> None:
        self.sched.start()

    def sma(self, *, period: int, price: str = "C") -> pd.DataFrame:
        return self.df[price].rolling(period).mean()

    def ema(self, *, period: int, price: str = "C") -> pd.DataFrame:
        return self.df[price].ewm(span=period).mean()

    def bbands(
        self, *, period: int = 20, band: int = 2, price: str = "C"
    ) -> Tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
        std = self.df[price].rolling(period).std()
        mean = self.df[price].rolling(period).mean()
        return mean + (std * band), mean, mean - (std * band)

    def macd(
        self,
        *,
        fast_period: int = 12,
        slow_period: int = 26,
        signal_period: int = 9,
        price: str = "C",
    ) -> Tuple[pd.DataFrame, pd.DataFrame]:
        macd = (
            self.df[price].ewm(span=fast_period).mean()
            - self.df[price].ewm(span=slow_period).mean()
        )
        signal = macd.ewm(span=signal_period).mean()
        return macd, signal

    def stoch(
        self, *, k_period: int = 5, d_period: int = 3
    ) -> Tuple[pd.DataFrame, pd.DataFrame]:
        k = (
            (self.df.C - self.df.L.rolling(k_period).min())
            / (self.df.H.rolling(k_period).max() - self.df.L.rolling(k_period).min())
            * 100
        )
        d = k.rolling(d_period).mean()
        return k, d

    def mom(self, *, period: int = 10, price: str = "C") -> pd.DataFrame:
        return self.df[price].diff(period)

    def rsi(self, *, period: int = 14, price: str = "C") -> pd.DataFrame:
        return 100 - 100 / (
            1
            - self.df[price].diff().clip(lower=0).rolling(period).mean()
            / self.df[price].diff().clip(upper=0).rolling(period).mean()
        )

    def ao(self, *, fast_period: int = 5, slow_period: int = 34) -> pd.DataFrame:
        return ((self.df.H + self.df.L) / 2).rolling(fast_period).mean() - (
            (self.df.H + self.df.L) / 2
        ).rolling(slow_period).mean()
예제 #30
0
#!/bin/python3

import os
import sys

from slack_webhook import Slack

WEBHOOK = os.getenv('SLACK_WEBHOOK', None)

if WEBHOOK is None:
    print("****** webhook is empty ******")
else:
    # Send to Slack
    slack = Slack(url=WEBHOOK)
    slack.post(text="Hey there! I just made a slack webhook!")