|
|
#!/usr/bin/env python3.7
|
|
|
"""
|
|
|
Detta är ELAB:s Slack-app.
|
|
|
|
|
|
Den har för närvarande i uppgift att göra "affiliate links" av Banggood-länkar.
|
|
|
"""
|
|
|
from slackeventsapi import SlackEventAdapter
|
|
|
from slack import WebClient
|
|
|
import os
|
|
|
import json
|
|
|
from furl import furl
|
|
|
import requests
|
|
|
import extruct
|
|
|
import html
|
|
|
import locale
|
|
|
|
|
|
|
|
|
def make_affiliate(url):
|
|
|
"""Tar en Banggood-URL och gör den till ELAB:s."""
|
|
|
u = furl(url)
|
|
|
# Lägg in ELABs ID. Egentligen vill vi skriva över endast parametern `p`,
|
|
|
# men för att komma runt en bugg med &-tecken rensar vi tills vidare bort
|
|
|
# alla parametrar.
|
|
|
# <https://github.com/slackapi/python-slack-events-api/issues/49>
|
|
|
# u.args['p'] = 'ZT07151453182201504Y'
|
|
|
u.args = {'p': 'ZT07151453182201504Y'}
|
|
|
|
|
|
return str(u)
|
|
|
|
|
|
|
|
|
def unfurl(url):
|
|
|
"""Skapar en presentation (rubrik, bild osv.) av en länk."""
|
|
|
# Ett semikolon hos Banggood kraschar extruct och måste plockas
|
|
|
# bort. <https://github.com/scrapinghub/extruct/issues/109>
|
|
|
page = requests.get(url).text.replace('};', '}')
|
|
|
|
|
|
ld = extruct.extract(page, syntaxes=['json-ld'])['json-ld'][0]
|
|
|
# Banggood verkar ha HTML-kodat den här strängen av slentrian, fast de nog
|
|
|
# inte borde göra så. Vi avkodar.
|
|
|
title = html.unescape(ld['name'])
|
|
|
image = ld['image']
|
|
|
offers = ld['offers']
|
|
|
if not isinstance(offers, list):
|
|
|
offers = [offers]
|
|
|
currency = offers[0]['priceCurrency']
|
|
|
if currency == 'SEK':
|
|
|
currency = 'kr'
|
|
|
prices = [float(offer['price']) for offer in offers]
|
|
|
|
|
|
return {'fallback': title + ' <' + url + '>',
|
|
|
'color': '#cf8e00', # ELAB-orange
|
|
|
# 'pretext': 'Text that appears above the attachment block',
|
|
|
'author_name': 'Banggood',
|
|
|
'author_link': make_affiliate('https://banggood.com/'),
|
|
|
'author_icon': 'https://www.banggood.com/favicon.ico',
|
|
|
'title': title,
|
|
|
'title_link': url,
|
|
|
# Utelämnas eftersom denna sträng från Banggood nästan aldrig
|
|
|
# innehåller något vettigt.
|
|
|
# 'text': ld['description'],
|
|
|
'fields': [{'title': 'Pris',
|
|
|
'value': ' – '.join(
|
|
|
[f'{price:n} {currency}' for price in
|
|
|
list(dict.fromkeys([min(prices), max(prices)]))]),
|
|
|
'short': True}],
|
|
|
# Visas som stor bild, vilket tar för mycket plats.
|
|
|
# 'image_url': image,
|
|
|
'thumb_url': image,
|
|
|
'footer': 'Använd denna länk för att gynna ELAB.',
|
|
|
'footer_icon': 'https://www.elab.kth.se/static/favicon.png',
|
|
|
# Endast om informationen är knuten till en viss tidpunkt
|
|
|
# 'ts': 123456789
|
|
|
}
|
|
|
|
|
|
|
|
|
# Our app's Slack Event Adapter for receiving actions via the Events API
|
|
|
# Signing token: <https://api.slack.com/apps/AN6HH95ML/general>
|
|
|
slack_signing_secret = os.environ['SLACK_SIGNING_SECRET']
|
|
|
slack_events_adapter = SlackEventAdapter(slack_signing_secret,
|
|
|
'/slack-eggberg/events')
|
|
|
|
|
|
# Create a WebClient for your bot to use for Web API requests
|
|
|
# Slack token börjar med "xoxp-". <https://api.slack.com/apps/AN6HH95ML/oauth>
|
|
|
token = os.environ['SLACK_TOKEN']
|
|
|
slack_client = WebClient(token)
|
|
|
|
|
|
|
|
|
# Prenumerera på eventet `link_shared`.
|
|
|
@slack_events_adapter.on('link_shared')
|
|
|
def link_shared(event_data):
|
|
|
"""Anropas när någon har postat en länk i Slack."""
|
|
|
urls = [link['url'] for link in event_data['event']['links']]
|
|
|
unfurls = json.dumps({url: unfurl(make_affiliate(url))
|
|
|
for url in urls})
|
|
|
|
|
|
slack_client.chat_unfurl(channel=event_data['event']['channel'],
|
|
|
ts=event_data['event']['message_ts'],
|
|
|
unfurls=unfurls)
|
|
|
|
|
|
|
|
|
# Sätt locale (för att få komma som decimaltecken).
|
|
|
locale.setlocale(locale.LC_ALL, 'sv_SE.UTF-8')
|
|
|
|
|
|
# Börja lyssna.
|
|
|
slack_events_adapter.start(port=8000)
|