ブログに戻る
4 min read 著者 著者

【jinba.flow】SlackからGithubに投稿を行う

SlackからGithubに投稿を行うというワークフローを紹介

【jinba.flow】SlackからGithubに投稿を行う

jinba.flowとjinba.appについて

Carnotでは、jinba.flowjinba.appという2つのツールを開発しています。

jinba.flowは、簡単な指示やノーコード操作で、データ変換、分析、AI活用、外部サービスとの連携など、日々の業務を自動化できるワークフロー作成ツールです。SlackやGmail、Googleスプレッドシートなどと自由に連携し、「面倒だけど人がやっていた作業」をスマートに置き換える仕組みを作ることが可能です。

Jinbaはこちらから

jinba.appは、自然言語によるチャットだけで、エージェントがMCPを組み合わせてタスクを処理してくれるツールです。ワークフローの生成が発生しないため、コードを書いたことがなくても、エンジニアリング技術・知識がなくても、誰でも・簡単に・タスクを処理することができ、より多くの人にお使いいただけます。

https://app.jinba.io/

SlackからGithubに投稿を行うワークフロー

今回はjinba.flowのテンプレートとして、SlackからGithubに投稿を行うというワークフローを紹介します。

このワークフローでは、Slack botへのアクセス権を持っている人であれば(その人が該当リポジトリのメンバーでない場合でも)が、バグを迅速に報告し、GitHubに追加できるようにすることを目的としています。

0.事前準備

このワークフローを実行するためには、①Slackアカウントとの連携②Githubアカウントとの連携が必要になります。

また、このワークフローはテンプレートからの読み込みを行なっていただく必要があります。
テンプレートのインポート方法については前回の記事で紹介しておりますので、こちらをご参考ください。

テンプレートはこちら

- id: slack_event
name: slack_event
tool: INPUT_SLACK_EVENT
config: []
input:
- name: value
value: |
{
"type": "app_mention",
"text": "@slack_bot #bug #web repo:flow title:Pressing X button crashes site desc:When I press the X button on the homepage, the entire site crashes and I have to refresh.",
"ts": "1736908626.0",
"channel": "C089XSKQ2QG",
"event_ts": "1735886205.0"
}
- id: process_message
name: process_message
tool: PYTHON_SANDBOX_RUN
config: []
input:
- name: code
value: |
import re
import json

# Get the message text and full event
message = steps.slack_event.result.text
full_event = steps.slack_event.result

# Initialize logging
logs = []
logs.append(f"Received message: {message}")
logs.append(f"Full event type: {type(full_event)}")
logs.append(f"Full event keys: {list(full_event.keys()) if isinstance(full_event, dict) else 'Not a dict'}")

# Initialize result variable
result = None

# Check if it's a help request
if "!help" in message:
logs.append("Help request detected")
result = {
"is_valid": False,
"is_help": True,
"message": "Valid labels: #bug, #web, #copilot, #tools, #enhancement\nFormat: @slack_bot #label1 #label2 repo:flow|app title:Your issue title desc:Detailed description",
"logs": logs
}
else:
# Extract all labels from the message
label_pattern = r'#(\w+)'
labels = re.findall(label_pattern, message)
logs.append(f"Found labels: {labels}")

# Check for valid format: <@USER_ID> #labels repo:type title:title desc:description
# The actual message format from Slack includes <@USER_ID> instead of @slack_bot
pattern = r'<@[A-Z0-9]+>\s+(?:#\w+\s+)*repo:(\w+)\s+title:(.*?)\s+desc:(.*)'
match = re.search(pattern, message, re.DOTALL)
logs.append(f"Regex match: {bool(match)}")

# If no match, try alternative pattern without the <@ format (for testing)
if not match:
alt_pattern = r'@slack_bot\s+(?:#\w+\s+)*repo:(\w+)\s+title:(.*?)\s+desc:(.*)'
match = re.search(alt_pattern, message, re.DOTALL)
logs.append(f"Alternative regex match: {bool(match)}")

if match and labels:
repo_type = match.group(1).lower()
title = match.group(2).strip()
description = match.group(3).strip()
logs.append(f"Parsed repo_type: {repo_type}")
logs.append(f"Parsed title: {title}")
logs.append(f"Parsed description: {description}")

valid_labels = ['bug', 'web', 'copilot', 'tools', 'enhancement']
valid_repos = {'flow': 'jinbaflow', 'app': 'lopeai'}

# Filter out invalid labels
valid_issue_labels = [label for label in labels if label.lower() in valid_labels]
logs.append(f"Valid labels: {valid_issue_labels}")

# Check if title and description exist and are not empty
if not title or not description:
logs.append("Title or description is empty")
result = {
"is_valid": False,
"is_help": False,
"message": "Both title and description are required. Ping me with !help for instructions."
}
elif valid_issue_labels and repo_type in valid_repos:
# Create a formatted label string for the title
result = {
"is_valid": True,
"labels": valid_issue_labels,
"repo": valid_repos[repo_type],
"title": title,
"description": description,
"issue_title": f"{title}",
"logs": logs
}
else:
logs.append("Invalid labels or repo type")
result = {
"is_valid": False,
"is_help": False,
"message": "Invalid format. Make sure to include valid labels, repo:flow or repo:app, a title, and a description. Ping me with !help for instructions.",
"logs": logs
}
else:
# If we get here, format is invalid
logs.append("Format is invalid - regex didn't match or no labels found")
result = {
"is_valid": False,
"is_help": False,
"message": "Invalid format. Make sure to include valid labels, repo:flow or repo:app, a title, and a description. Ping me with !help for instructions.",
"logs": logs
}

# The last expression is automatically returned
result
- name: data_type
value: OBJECT
needs:
- slack_event
- id: create_issue
name: create_issue
when: "{{steps.process_message.result.data.is_valid}} == true"
tool: GITHUB_CREATE_AN_ISSUE
config:
- name: token
value: "{{ secrets.JINBA_SLACK_PAT.value }}"
input:
- name: owner
value: carnot-tech
- name: repository
value: "{{steps.process_message.result.data.repo}}"
- name: title
value: "{{steps.process_message.result.data.title}}"
- name: labels
value: "{{steps.process_message.result.data.labels | dump}}"
- name: body
value: |-
{{steps.process_message.result.data.description}}

*Reported via Slack*
needs:
- process_message
- id: send_success_response
name: send_success_response
when: "{{steps.process_message.result.data.is_valid}} == true"
tool: SLACK_POST_MESSAGE
config:
- name: token
value: "{{ secrets.SLACK_GITHUB_SENDER.token }}"
input:
- name: channel
value: "{{steps.slack_event.result.channel}}"
- name: thread_ts
value: "{{steps.slack_event.result.ts}}"
- name: text
value: "Issue created successfully! View it here: {{steps.create_issue.result.html_url}}"
needs:
- create_issue
- id: send_help_response
name: send_help_response
when: "{{steps.process_message.result.data.is_valid}} == false && {{steps.process_message.result.data.is_help}} == true"
tool: SLACK_POST_MESSAGE
config:
- name: token
value: "{{ secrets.SLACK_GITHUB_SENDER.token }}"
input:
- name: channel
value: "{{steps.slack_event.result.channel}}"
- name: thread_ts
value: "{{steps.slack_event.result.ts}}"
- name: text
value: "{{steps.process_message.result.data.message}}"
needs:
- process_message
- id: send_error_response
name: send_error_response
when: "{{steps.process_message.result.data.is_valid}} == false && {{steps.process_message.result.data.is_help}} == false"
tool: SLACK_POST_MESSAGE
config:
- name: token
value: "{{ secrets.SLACK_GITHUB_SENDER.token }}"
input:
- name: channel
value: "{{steps.slack_event.result.channel}}"
- name: thread_ts
value: "{{steps.slack_event.result.ts}}"
- name: text
value: "{{steps.process_message.result.data.message}}"
needs:
- process_message


1. テンプレートをインストールする。


上記のテンプレートをインストールすると、上記のような画面になります。
この画面内で各モジュールをクリックすると、ツールとの連携が行えますので、ここでご自身のアカウントとの紐付けを行います。


2.Slack上で内容を投稿する


連携が完了後、Slack上でBotにメッセージを送るとスレッドに返答が返ってくる仕組みになっています。
”help”と送るとBotの使い方が返ってきます。


実際にバグの報告を投稿すると、Githubへの投稿が完了したURLがSlackに返ってきます。
URLをクリックしてGithubを確認すると、Slackから投稿した内容が記載されていることが確認できます。


注意点

このワークフローは社内での利用を想定しています。そのため、使用する際は以下のような詳細を調整する必要があります:

  • イシューに使用したいタグの設定
  • 有効なリポジトリのリスト
  • 作成されるイシューのテンプレートを変更したい場合の編集内容 など


動画でも紹介

このタスクの概要動画は公式Xでアップしています。
ぜひ動画でも実際の流れをご確認ください!

jinba.flowはこちらから

この記事で紹介したワークフローは、 jinba.flow へ登録後すぐに使えます。
ユーザー登録は公式サイトから無料で行っていただけますので、実際に操作を試してみてください!

なお、ワークフローを実行するためには、jinba.flowの登録が必要になります。以前のjinbaflowのアカウント/jinba.appとは別のアカウントが必要となりますので、ご注意ください。


お問い合わせ

ご質問や不明点のほか、「こんなことができたら嬉しい」「こういう機能を作ってほしい」といったご意見・ご要望もぜひお寄せください。

📩 お問い合わせ:  contact@carnot.ai