Статьи

Интеграция Neo4j-Slack, которую вы ждали (уже здесь)

Наш коллега Андреас , который любит Slack и привел его в нашу компанию, на днях предложил, чтобы мы могли создать интеграцию Slack и Neo4j, чтобы продемонстрировать, насколько полезной была бы база данных графовой базы данных.

И, конечно же, сколько веселья.

Прочитайте все о нашей интеграции Neo4j-Slack, которая генерирует рекомендуемые каналы для других пользователей

В процессе интеграции мы получили неожиданно полезные преимущества. Подробнее ниже.

Строительные блоки

Поскольку была только полночь, мы, удивительные Николь и Майкл , решили что-то собрать.

Мы создали экземпляр Neo4j 2.2.3 в облаке .

Затем мы создали приложение Python для нашего сервера Slack-Neo4j и отправили его на GitHub .

Приложение использует веб- приложение web.pyдля requestsдоступа к API Slack и py2neo для общения с Neo4j.

Затем мы отправили его Heroku, чтобы сделать его общедоступным, чтобы Slack мог подключиться к нему.

Вы должны предоставить переменные среды вашему серверу Neo4j, вашему токену Slack API и токену команды, сконфигурированному с вашей командой slash. Найти подробности в проекте readme .

Slack Slash Command

После всего этого мы могли бы установить команду слэша . Для нашей интеграции идеи пришли от Андреаса:

  • /graph import — импортировать пользователей, каналы и членство в Neo4j
  • /graph cypher MATCH ... RETURN — выполнить оператор шифрования только для чтения и вернуть результаты
  • /graph — предоставить обзор данных, находящихся в базе данных

Реализация приложения была простой. Разобрав POSTполезную нагрузку и проверив токен команды, мы получили первое слово textпараметра как «команда» для отправки.

Получение данных из Slack в Neo4j

Для интеграции с Neo4j мы отправили операторы Cypher в Neo4j с помощью API py2neo. Пример ниже:

from py2neo import Graph
graph = Graph(os.environ.get('NEO4J_URL'))

graph.cypher.execute("MATCH (u:User)-[:MEMBEROF]->(c:Channel) return u.screenname, c.name")

Отправка запросов в Slack API с помощью токена и получение ответа JSON просты requests. Затем мы передали ответ JSON непосредственно в качестве параметров в оператор Cypher для создания структуры графа в Neo4j.

res = requests.get("https://slack.com/api/channels.list?token={}".format(token))

query = """
UNWIND {channels} AS channel
MERGE (c:Channel {id:channel.id}) ON CREATE SET c.name = channel.name
"""
graph.cypher.execute_one(query, res.json())

Как видите, мы можем импортировать пользователей, каналы и подписки, просто peasy.

/graph import channels

slackbot: загружено 115 пользователей. Только вы можете увидеть это сообщение

/graph import users

slackbot: 117 каналов загружено Только вы можете видеть это сообщение

График все слабины

И чтобы показать вам, что это работает, вот график нашей вселенной Slack:

И вот несколько запросов, которые показывают наиболее плодовитые люди:

/graph cypher match (u:User)-->() return u, count(*) as memberships order by memberships desc limit 3`

slackbot:
   | u                                                            | memberships
---+--------------------------------------------------------------+-------------
1 | (n200:User {fullname:"Michael",id:"U02HVJ36",username:"mh"})  |          64
2 | (n151:User {fullname:"Chris",id:"U0KLMP5X",username:"cl"})    |          37
3 | (n210:User {fullname:"Philip",id:"U02HDEF0EX",username:"pr"}) |          37

рекомендации

Наконец, самый большой сюрприз из всех: мы хотели рекомендовать новые каналы людям.

Мы использовали традиционную совместную фильтрацию для этой концепции «каналы ваших коллег, которые еще не ваши каналы». Но мы также отфильтровываем многочисленных пользователей и каналы, чтобы они не искажали картину.

/graph cypher
MATCH (c:Channel) with toInt(count(*)*0.618) as channel_cutoff
MATCH (u:User) with toInt(count(*)*0.618) as user_cutoff, channel_cutoff

MATCH (u:User {username:"laeg"})-[:MEMBER_OF]->(c:Channel)
      <-[:MEMBER_OF]-(coll:User)-[:MEMBER_OF]->(reco:Channel)

WHERE size((c)<--())    < channel_cutoff
  AND size((reco)<--()) < channel_cutoff
  AND size((coll)-->()) < user_cutoff
  AND NOT (u)-[:MEMBER_OF]->(reco)

RETURN reco.name, count(*) AS freq
ORDER BY freq DESC
LIMIT 5;



slackbot:
  | reco.name           | freq
--+---------------------+------
1 | feedback            |  218
2 | dev-team            |  179
3 | sales_marketing     |  161
4 | marketing           |  142
5 | cypher-the-language |  125

Мы надеемся, что эта интеграция между Neo4j как графической базой данных с открытым исходным кодом и совместным чудо-инструментом, известным как Slack, превратит ее в страницу интеграции Slack сообщества .