GASとslackでヘルプデスクフォームを作った話(スラッシュコマンド版 コード編)

GASとslackでヘルプデスクフォームを作った話(スラッシュコマンド版 準備編)の続きです。

処理の流れ

doPostで受けとったデータの内容によって分岐するようにしています。

スラッシュコマンドからのリクエストの場合

  1. トークンのチェック
  2. スラッシュコマンドのチェック
  3. フォームを作成しslackへ返す(表示させる)

フォームからのリクエストの場合

  1. フォームのcallback_idをチェック
  2. 質問者のslackのユーザーIDからメールアドレスを取得
  3. 内容をGSSに書き込む
  4. 質問者をチャンネルへ招待
  5. 内容をチャンネルへポスト

コード全体

コメントアウトで説明を入れています。

function doPost(e) {

  //スクリプトのプロパティからトークンやIDを取得
  var verifiy_token = PropertiesService.getScriptProperties().getProperty('verifiy_token'); //slackアプリ Basic InformationのVerification Token
  var bot_token = PropertiesService.getScriptProperties().getProperty('bot_token'); //slackアプリ OAuth & PermissionsのBot User OAuth Access Token
  var channel_id = PropertiesService.getScriptProperties().getProperty('channel_id'); //#helpdeskのチャンネルID
  var gss_id = PropertiesService.getScriptProperties().getProperty('gss_id'); //スプレッドシートのID
  var sup_mem1 = PropertiesService.getScriptProperties().getProperty('sup_mem1'); //サポートメンバー1のslackUserID
  //メンバー数に応じて、必要があれば追加してください。(スクリプトプロパティも)
  //var sup_mem2 = PropertiesService.getScriptProperties().getProperty('sup_mem2'); //サポートメンバー2のslackUserID
  
  var time = new Date(); //投稿時間作成用に現在時刻を取得
  
  //verification tokenの検証
  var verification_token = e.parameter.token || JSON.parse(e.parameter.payload).token || null;  //リクエストされたトークンを格納
  if (verification_token !== verifiy_token) { // アプリのトークンと一致しない場合終了
    return ContentService.createTextOutput();
  }
  
  //----------------------------------------スラッシュコマンドから投稿された場合の処理
  if (e.parameter.command === "/helpjosys") {
    var created_dialog = createDialog(e,bot_token); //ダイアログを作成する
    var response = UrlFetchApp.fetch("https://slack.com/api/dialog.open", created_dialog); //チャンネルへポストする
    return ContentService.createTextOutput(); //空文字をreturnしないとダイアログが消えない
    
    //----------------------------------------フォーム(Dialog)から投稿された場合の処理
  } else {
    var p = JSON.parse(e.parameter.payload);
    var s = p.submission;
    
    if (p.callback_id === "helpdesk_dialog") { //想定しているフォームからの投稿かチェック
    
      //質問者のslack User IDから、メールアドレスと取得
      var user_email = findUserBySlackID(p.user.id,bot_token)
      
      //スプレッドシートへ記録
      var spread_sheet = SpreadsheetApp.openById(gss_id);
      var sheet_name = "helplist";
      var no = spread_sheet.getSheetByName(sheet_name).getLastRow() //現在の最終行を管理Noにする
      spread_sheet.getSheetByName(sheet_name).appendRow(
        [no,
         time,
         user_email,
         p.user.id,
         s.username, //s.*****の*****はfunction createDialogで作成したelementsのnameです
         s.urgency,
         s.question_content
        ]
      )
      
      //質問者をチャンネルへ招待
      var created_invite = createInvite(p.user.id,bot_token,channel_id)
      var response = UrlFetchApp.fetch("https://slack.com/api/conversations.invite", created_invite);
      
      //チャンネルへポスト
      var message_data = "<@" + sup_mem1 + ">" // サポートメンバー増があれば必要に応じて追加<@" + sup_mem2 + ">"
      + "\n<@" + p.user.id + "> から問い合わせがありました。"
      + "\n\n*No*\n" + no
      + "\n\n*氏名*\n" + s.username
      + "\n\n*緊急度*\n" + s.urgency
      + "\n\n*問い合わせ内容*\n" + s.question_content
      var created_message = createMessage(message_data,bot_token,channel_id)
      var response = UrlFetchApp.fetch("https://slack.com/api/chat.postMessage", created_message);
    }
    return ContentService.createTextOutput();
  }
  return ContentService.createTextOutput();
}
//----------------------------------------フォーム(Dialog)作成
function createDialog(e,bot_token){
  var trigger_id = e.parameter.trigger_id;
  var dialog = {
    "token": bot_token,
    "trigger_id": trigger_id,
    "dialog": JSON.stringify(
      {
        "callback_id": "helpdesk_dialog",
        "title": "ヘルプデスクフォーム",
        "submit_label": "送信する",
        "elements": [
          {
            "type": "text",
            "label": "氏名",
            "name": "username",
            "placeholder": "佐藤裕也(`ェ´)ピャー" //記入例を表示させたい場合placeholderを使用
          },
          {
            "type": "select",
            "label": "緊急度",
            "name": "urgency",
            "options": [
              {
                "label": "低 (1週間以上)",
                "value": "低 (1週間以上)"
              },
              {
                "label": "中 (1週間以内)",
                "value": "中 (1週間以内)"
              },
              {
                "label": "高 (3日以内)",
                "value": "高 (3日以内)"
              },
              {
                "label": "緊急 (当日)",
                "value": "緊急 (当日)"
              }]
          },
          {
            "type": "textarea",
            "label": "問い合わせ内容",
            "name": "question_content",
            "placeholder": "なにもしてないのにパソコンがこわれた"
            //"optional":"true" ←これを追加することで任意の項目になる(直前にカンマ追加も忘れないよう)
          }
        ]}
    )
  }
  var options = {
    'method' : 'POST',
    'payload' : dialog
  }
  return options;
}
//----------------------------------------slackIDからメールアドレスを取得
function findUserBySlackID(slackID){
  var url="https://slack.com/api/users.info"  
  var payload = {
    "token" : bot_token,
    "user" : slackID
  }
  var options = {
    "method" : "GET",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  
  var json_data = UrlFetchApp.fetch(url, options);
  var otp = json_data
  json_data = JSON.parse(json_data)
  
  if (json_data["ok"]){
    var user_email = String(json_data["user"]["profile"]["email"])
    } else {
      var user_email = "null" //slackユーザーが居てメールが無いことはないと思いますが念のため
      }
  
  return user_email
}
//----------------------------------------postMessage作成
function createMessage(message_data,bot_token,channel_id){
  var payload = {
    "token" : bot_token,
    "channel" : channel_id,
    "text" : message_data
  }
  var options = {
    "method" : "POST",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  return options;
}
//----------------------------------------Invite作成
function createInvite(user_id,bot_token,channel_id){
  var payload = {
    "token" : bot_token,
    "channel" : channel_id,
    "users" : user_id
  }
  var options = {
    "method" : "POST",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  return options;
}

スクリプトプロパティの設定

Googleフォーム版と同様に設定してきます。

下記のパラメータを設定します。

sup_mem1
 サポートメンバーのslackユーザーID(メンション通知用)
 ※ユーザーIDの調べ方は別途ググってくださいm(_ _)m
gss_id
 スプレッドシートのID
bot_token
 slackアプリのOAuth & Permissions → Bot User OAuth Access Token
channel_id
 slackのヘルプデスク用チャンネルのID
verify_token
 slackのアプリのBasic Information → Verification Token

Verification Tokenはこちら

f:id:simple-josys:20200502153954p:plain:w500

functionの説明

doPost

メインの処理

createDialog

dialog.openメソッドに必要な中身を作る処理
メイン処理の中に入れるとハイパー見辛いので

findUserBySlackID

slackからユーザーリストを貰い、ユーザーIDを元にメールアドレスを探す処理

createMessage

chat.postMessageメソッドに必要な中身を作る処理

createInvite

channels.inviteメソッドに必要な中身を作る処理

権限のチェック

コードが完成したら、保存して再度公開しましょう。

f:id:simple-josys:20200502140520p:plain:w500


その際に、新たに権限が必要なコードが追加されていた場合、許可を求められるので許可します。

f:id:simple-josys:20200429225326p:plain

実行テスト

スラッシュコマンドの実行

コマンド入力→送信

f:id:simple-josys:20200502161248p:plain:w500


フォームが表示されます(`ェ´)ピャー

f:id:simple-josys:20200502161358p:plain:w500


入力せずに送ろうとすると怒られます。

f:id:simple-josys:20200502161541p:plain:w200

slackの通知

入力して送信します。

f:id:simple-josys:20200502161705p:plain:w500


うまく投稿されました。

f:id:simple-josys:20200502195725p:plain

スプレッドシートの記録

こちらも問題ないようです。

f:id:simple-josys:20200502162120p:plain:w500

終わりに

いかがでしたでしょうか。
色々な記事を参考にさせていただいて、自分で運用しやすいようにいろいろ弄っているのでオリジナリティはそれほどありませんが…。

スプレッドシートへ書き込む部分で、「Googleフォーム経由」とか「slack経由」とか書けば見分けを付けることもできます。
e.parameterを別シートに記録することで実行ログ的なものを記録することもできます。

余力があればチケット管理サービスと連携させてみたいです。

修正

2020/10/16
channelsAPIが廃止予定のため、channels.invite→conversations.inviteへ変更

2021/8/11
function findUserBySlackIDの手法を変更(users.list API → users.info API)

GASとslackでヘルプデスクフォームを作った話(スラッシュコマンド版 準備編)

前回の記事で紹介した、GASとslackでヘルプデスクフォームを作った話(Googleフォーム版)の起点を、
Googleフォームではなくスラッシュコマンドから行うパターンの作成方法の紹介です。
重複する内容が多くあるので、slackアプリ作成の部分等は前回の作業の差分のみ書いていきます。

今回も準備編とコード編に分けて書きます。

動作の流れ

  1. ユーザーがslackのスラッシュコマンドを送信
  2. slack上にフォームが表示され、そこからヘルプ内容を投稿
  3. フォームの内容を、スプレッドシートに記録
  4. 質問した人をslackの専用チャンネルへ招待する
  5. フォームの内容を、slackの専用チャンネルにポストして、情シスへメンションを送る

必要なもの

事前準備

GASの準備

新しいプロジェクトを作成し、いったん保存します。
GASはスタンドアロン型でOKです。

f:id:simple-josys:20200502140133p:plain:w500

f:id:simple-josys:20200502140357p:plain


作成したGASをWebアプリケーションとして公開します。

f:id:simple-josys:20200502140520p:plain:w500


公開設定等を聞かれるので、次のように設定します。
Project versionNew
Excute the app asMe
Who has access to the appAnyone , even anonymous

解説
コードを更新するごとに、都度公開する必要があります。
その時に、2回目以降はProject versionを手動でNewにする必要があります。
Excute the app asは、アプリの実行者です。
Who has asccess to the appはアプリにアクセス可能な人の設定です。今回はslackがリクエスト元になるので、誰でもOK(非ログイン状態でもOK)にしています。

f:id:simple-josys:20200502140833p:plain


Current web app URLは後で使用するので控えておきます。

f:id:simple-josys:20200502141606p:plain

slackアプリの準備

Googleフォーム版と同様に作成し、追加で必要な設定を書いていきます。

スラッシュコマンドの作成

実行に必要なコマンドを作成していきます。

左メニューの「Slash Commands」→「Create New Command

f:id:simple-josys:20200502143631p:plain:w500


スラッシュコマンドのパラメータを設定していきます。

必須
Command → 実行したいときに打つコマンド
Request URL → さっき公開した、GASのURL(Current web app URL)

任意
Short Description → コマンドの簡単な説明
Usage Hint → コマンド以外にパラメータを入力させるときのヒント

f:id:simple-josys:20200502144327p:plain:w500


アプリを再インストールしてくださいと言われますが、一旦無視します。(もう1点設定を変更するため)

f:id:simple-josys:20200502144837p:plain:w500

Interactivity & Shortcutsの設定

Interactivityは、フォーム(ダイアログ)やボタン等からリクエストがあった時にどのURLにリクエストするか設定するものです。
そのためスラッシュコマンドを受け取って実行するGASと、フォームやボタンから受けたリクエストを処理するGASを分けることもできます(たぶん)

左メニューの「Interactivity & Shortcuts」をクリックし、右上のツマミを「On」にします。

f:id:simple-josys:20200502145021p:plain:w500


今回は1つのGASでスラッシュコマンドもフォームの処理も行うので、
Request URLGASのURL(Current web app URL)を入れます。

f:id:simple-josys:20200502145508p:plain:w500


設定が終わったのでアプリをワークスペースに再インストールします。

左メニューの「Install App」→「Reinstall App

f:id:simple-josys:20200502145902p:plain:w500


許可を求められるので、投稿先チャンネル(ヘルプデスク用のチャンネル)を指定し、許可します。

f:id:simple-josys:20200502150103p:plain:w500


アプリの準備はこれで完了です。

slackチャンネルの準備

Googleフォーム版と同様です。

GASとslackでヘルプデスクフォームを作った話(Googleフォーム版 コード編)

GASとslackでヘルプデスクフォームを作った話(Googleフォーム版 準備編)の続きです。

コード全体

コメントアウトで説明を入れています。

function onFormSubmit(e){
  FormApp.getActiveForm() //フォームを取得
  
  //スクリプトのプロパティからトークンやIDを取得
  var bot_token = PropertiesService.getScriptProperties().getProperty('bot_token') //slackアプリ OAuth & PermissionsのBot User OAuth Access Token
  var channel_id = PropertiesService.getScriptProperties().getProperty('channel_id') //#helpdeskのチャンネルID
  var gss_id = PropertiesService.getScriptProperties().getProperty('gss_id') //スプレッドシートのID
  var sup_mem1 = PropertiesService.getScriptProperties().getProperty('sup_mem1') //サポートメンバー1のslackUserID
  //メンバー数に応じて、必要があれば追加してください。(スクリプトプロパティも)
  //var sup_mem2 = PropertiesService.getScriptProperties().getProperty('sup_mem2'); //サポートメンバー2のslackUserID
  
  var time = e.response.getTimestamp() //投稿日時をフォームから取得
  
  var email = e.response.getRespondentEmail() //メールアドレスの回答を取得
  var form_items = e.response.getItemResponses() // 質問内容と回答が格納されています。
  var q1 = form_items[0].getResponse() // 氏名の回答を取得
  var q2 = form_items[1].getResponse() // 緊急度の回答を取得
  var q3 = form_items[2].getResponse() // 詳細の回答を取得
  
  //メールアドレスからslackUserIDを取得
  var user_id = findUserByEmails(email,bot_token)
  
  //スプレッドシートへ記録
  var sheet_name = "helplist" //スプレッドシートのシート名
  var spread_sheet = SpreadsheetApp.openById(gss_id)
  var no = spread_sheet.getSheetByName(sheet_name).getLastRow() //最終行から管理Noを決定
  spread_sheet.getSheetByName(sheet_name).appendRow( //最終行へ記入
    [no,time,email,user_id,q1,q2,q3]
  )
  
  //送信者のslackユーザーを招待、メンションの準備をする。居ない場合はメールアドレス
  if (user_id == "null"){
    var applicant = email
    } else {
      var applicant = "<@" + user_id + ">" //送信者へメンションする書式
      var created_invite = createInvite(user_id,bot_token,channel_id) //チャンネルへ招待
      var response = UrlFetchApp.fetch("https://slack.com/api/conversations.invite", created_invite);
    }
  
  //チャンネルへ投稿
  var message_data = "<@" + sup_mem1 + ">" // サポートメンバー増があれば必要に応じて追加<@" + sup_mem2 + ">"
  + "\n" + applicant + " から問い合わせがありました。"
  + "\n\n*No*\n" + no
  + "\n\n*氏名*\n" + q1
  + "\n\n*緊急度*\n" + q2
  + "\n\n*問い合わせ内容*\n" + q3
  var created_message = createMessage(message_data,bot_token,channel_id)
  var response = UrlFetchApp.fetch("https://slack.com/api/chat.postMessage", created_message);
  
}
//---------------------------------------メールアドレスからslackIDを取得
function findUserByEmails(email,bot_token){
  var url="https://slack.com/api/users.lookupByEmail"  
  var payload = {
    "token" : bot_token,
    "email" : email
  }
  var options = {
    "method" : "GET",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  
  var json_data = UrlFetchApp.fetch(url, options);
  json_data = JSON.parse(json_data)
  
  if (json_data["ok"]){
    var user_id = String(json_data["user"]["id"])
    } else {
      var user_id = "null"
      }
  
  return user_id
}
//---------------------------------------postMessage作成
function createMessage(message_data,bot_token,channel_id){
  var payload = {
    "token" : bot_token,
    "channel" : channel_id,
    "text" : message_data
  }
  var options = {
    "method" : "POST",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  return options;
}
//---------------------------------------invite作成
function createInvite(user_id,bot_token,channel_id){
  var payload = {
    "token" : bot_token,
    "channel" : channel_id,
    "users" : user_id
  }
  var options = {
    "method" : "POST",
    "payload" : payload,
    "headers": {
      "contentType": "x-www-form-urlencoded",
    }
  }
  return options;
}

スクリプトプロパティの設定

ファイル」→「プロジェクトプロパティ

f:id:simple-josys:20200429221414p:plain


スクリプトのプロパティ」に準備編で作成したトークンやIDをセットします。


sup_mem1
 サポートメンバーのslackユーザーID(メンション通知用)
 ※ユーザーIDの調べ方は別途ググってくださいm(_ _)m
gss_id
 スプレッドシートのID
bot_token
 slackアプリのOAuth & Permissions → Bot User OAuth Access Token
channel_id
 slackのヘルプデスク用チャンネルのID

f:id:simple-josys:20200429222508p:plain:w500

権限のチェック

GASの権限をチェックしたいので、一度実行します。

f:id:simple-josys:20200429233810p:plain:w500


この画面が出た場合、権限が不足している場合があるので許可します。
フォームからpostされるはずのデータが無いので、許可後は必ずエラーが出ます。
f:id:simple-josys:20200429225326p:plain

実行テスト

slackユーザーが居る場合(メンション)

投稿内容

f:id:simple-josys:20200429234052p:plain:w300


slack通知画面

f:id:simple-josys:20200429235319p:plain

slackユーザーが居ない場合(メールアドレス表記)

f:id:simple-josys:20200429234459p:plain:w300


slack通知画面

f:id:simple-josys:20200429235610p:plain

終わりに

GASもslackアプリもまだまだ初心者なので、解釈が間違っている部分や効率化できる部分があると思います。
ここが間違っている、こうした方がもっと良い、といった点があればコメントいただけると嬉しいです!

修正

2020/10/16
channelsAPIが廃止予定のため、channels.invite→conversations.inviteへ変更

2021/8/11
function findUserByEmailsの手法を変更(users.list API → users.lookupByEmail API)

GASとslackでヘルプデスクフォームを作った話(Googleフォーム版 準備編)

お久しぶりです。カインです。

初めて情シスらしい記事を書きます(笑)

 

GAS(Google Apps Script)とslackを使った社内用ヘルプデスクフォームを作ったので、その紹介です。

今回の記事はGoogleフォームを起点としたものです。

色々な記事を参考にしておりますので、類似点等があるかもしれませんがご容赦ください。

後日、slackのスラッシュコマンドを起点にしたものも書く予定です。

 

長いので、準備編とコード編に分けて書きます。

後半→GASとslackでヘルプデスクフォームを作った話(Googleフォーム版 コード編)

作った人のスペック

この程度の人間でも作れるよ!というアピール

  • 情シス歴3年(公務員2年、民間1年)
  • プログラミングの勉強経験はCの基礎的な部分のみ
  • Excel関数、AccessVBA等を独学で勉強して業務改善をした程度
  • GAS(JavaScript)は初心者

動作の流れ

  1. ユーザーがGoogleフォームからヘルプ内容を投稿
  2. フォームの内容を、スプレッドシートに記録
  3. 質問した人のメールアドレスからslackのユーザーを特定し、slackの専用チャンネルへ招待する
  4. フォームの内容を、slackの専用チャンネルにポストして、情シスへメンションを送る

必要なもの

事前準備

GASでコードを書いていく部分以外に必要なものを準備していきます。

GoogleフォームとGAS(コンテナバインド型)の準備

Googleフォームの作成

まずフォームを作成します。

今回は、

  • メールアドレス
  • 氏名
  • 緊急度
  • 詳細

の4項目でフォームを作成します。

メールアドレスの項目は、歯車アイコンをクリックして「メールアドレスを収集する」にチェックを入れて保存します。

今回は手動で入力させる形ですが、フォームの公開組織を限定することで、ログインユーザーから自動収集することもできます。

G Suiteアカウントに入れなくなった事態を想定して手動入力にしています。

f:id:simple-josys:20200429210042p:plain

f:id:simple-josys:20200429210209p:plain

 

項目を足していき、完成したフォームはこんな感じになりました。

f:id:simple-josys:20200429210702p:plain

 

GAS(コンテナバインド型)の作成

次に、このフォームに紐づいたコンテナバインド型のGASを作成します。

編集画面右上の「・・・」メニューから、「スクリプト エディタ」を開きます。

f:id:simple-josys:20200429210857p:plain

 

プロジェクト名を適当に決めて、いったん保存します。

f:id:simple-josys:20200429211301p:plain

f:id:simple-josys:20200429211421p:plain

 

トリガーの作成

フォーム送信時にこのGASが動作するように、トリガーを作成します。

先にfunction名を決める必要があるので、後で書く予定の「onFormSubmit」にしておきます。

f:id:simple-josys:20200429212038p:plain

 

編集」→「現在のプロジェクトのトリガー」をクリックします。

f:id:simple-josys:20200429212134p:plain

 

ページ右下の「トリガーを追加」をクリックします。

f:id:simple-josys:20200429212522p:plain


イベントの種類を選択→フォーム送信時 に変更して保存します。

f:id:simple-josys:20200429212706p:plain

 

これで、フォームが送信されたときに「function onFromSubmit」が実行されるようになりました。

スプレッドシートの準備

記録用のスプレッドシートを作成しておきます。

 

スプレッドシートのIDを控えておきます。

スプレッドシートのIDは、URLのxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxの部分です。

https://docs.google.com/spreadsheets/d/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/edit#gid=0

 

1行目はフィールド名を適当に入れておきましょう。

f:id:simple-josys:20200429231358p:plain

 

slackアプリの準備

まずはアプリを作成します。

slackメニュー→「設定と管理」→「アプリを管理する

f:id:simple-josys:20200429184228p:plain

 

ページ上部の「ビルド

f:id:simple-josys:20200429184415p:plain

 

ページ上部の「Your Apps

f:id:simple-josys:20200429184733p:plain

 

Create New App

f:id:simple-josys:20200429184906p:plain

 

アプリの名前とインストール先のワークスペースを決定して、「Create App

f:id:simple-josys:20200429185055p:plain

 

これでアプリは作成できたので、色々設定をいじっていきます。

Incoming Webhooks

botがチャンネルにデータを送信できるようにする設定です。

 

左メニューの「Incoming Webhooks」をクリックし、右上のツマミを「On」にします。

f:id:simple-josys:20200429223450p:plain

 

OAuth & Permissions

ここでは、アプリに持たせる権限を設定します。

今回のGoogleフォーム版では、

  • botがチャンネルに書き込む権限
  • botがユーザーをチャンネルに拉致招待する権限
  • botがユーザーデータを取得する権限

を付与したいです。

 

左メニューの「OAuth & Permissions」をクリックします。

f:id:simple-josys:20200429190732p:plain

 

Bot Token Scopesの「Add an OAuth Scope」をクリックして、

  • chat:write
  • users:read
  • users:read.email
  • channels:manage

下記も追加(2020/10/16追記)

  • groups:write
  • im:write
  • mpim:write

を追加します。

f:id:simple-josys:20200429232731p:plain

 

ちなみに、どの権限を追加するかは、使用するAPIのメソッドによります。

今回はこの3つのメソッドを使います。

それぞれのメソッドのページに、「Works with」の部分に必要な権限(Required scope(s))が書いてあります。

https://api.slack.com/methods/chat.postMessage

https://api.slack.com/methods/users.list

https://api.slack.com/methods/channels.invite

 

Incoming WebhooksOAuth & Permissionsの設定が済んだら、「Install App to Workspace」をクリックします。

f:id:simple-josys:20200429202523p:plain

 

Incoming Webhooksの投稿先を聞かれるので、作成したチャンネル(#helpdesk)を指定し、「許可する」をクリックします。

f:id:simple-josys:20200429223756p:plain

 

許可後にトークンが作成されるので、「Bot User OAuth Access Token」を控えておきます。

f:id:simple-josys:20200429203458p:plain

 

slackチャンネルの準備

専用のチャンネルを適当に作成して、チャンネルにアプリを追加します。

ここでは、チャンネル名は#helpdeskとしています。

f:id:simple-josys:20200429204223p:plain

 

先ほど作ったアプリを追加します。

f:id:simple-josys:20200429204428p:plain

 

このチャンネルのチャンネルIDを控えておきます。

チャンネルIDは、URLのYYYYYYYYYYYの部分です。

https://app.slack.com/client/XXXXXXXXX/YYYYYYYYYYY

 

コード編

後半→GASとslackでヘルプデスクフォームを作った話(Googleフォーム版 コード編)

グラボのコード43エラーでハマった話

お久しぶりです。カインです。

見事に三日坊主がキマって1ヶ月近く放置していました。

新型HHKBを購入して文字が打ちたくなったので投稿します。

 

私事ではありますが、2年ほど悩まされていた問題が解決されたので事例として紹介します。

よくある話でもないのでサクっと端折って書きます。

グラフィックボードのドライバでエラー発生

私の現在のメインPCは2016年6月頃に自作し、今も稼働しています。

とある日、次のようなエラーが発生しました。

f:id:simple-josys:20191214010514p:plain

 

問題が発生したのでこのデバイスは停止しました。(コード 43)

このエラーはドライバが異常だからグラボを正常に認識できないYO!というもので、画像処理にグラボが使用できません(たぶん)

手あたり次第解決策を試す

  • Windows 10のダウングレード

1803から1709に戻すことで正常に認識するようになり、当面はこれで凌いできましたが、サポートも終了し騙し騙し使うのも難しくなってきたので重い腰を上げて、「nvidia code43」等のキーワードでググり、引っかかったものを手あたり次第試しました。

  • DDUを使ってドライバを完全にアンインストールしてから再インストール
  • 上記の手段で複数のバージョンのドライバを試行
  • マザーボードBIOS(UEFI)のアップデート
  • BIOS(UEFI)の設定変更(オンボードグラフィックの無効化)
  • VIRTU MVPのアンインストール(もともと入れていない)
  • Windowsの初期化

どれを試してもだめでした。

文字で書くとこれだけのことしかしてませんが、再インストールや初期化はめちゃくちゃ時間がかかるので心が折れそうになります。

色々試したところ、Windows 10 1709、NVIDIA 382.05では正常に動作するようだが、1803に上げてもだめ、ドライバを変えてもダメでした。

解決に至った手段

諦めかけていたとき、グラボのBIOSのカスタマイズや、コード43エラーのフォーラムで電圧を変えたら直ったという情報を見つけました。

グラボのBIOSは自分では弄ってないけど、メーカーのカスタムや前オーナーが弄っている可能性があるかも…と思いダメ元でやってみました。

forums.guru3d.com

BIOSのデータを入手する

VGA Bios Collection | TechPowerUp

このサイトからグラボのBIOSを入手します。

何個かBIOSがありましたが、最もCore/Mem/Boostが低いものを選びました。

BIOSを上書きする

NVIDIA NVFlash Download | TechPowerUp

NVFlashというツールを使い、グラボのBIOSを書き換えます。

コマンドはこちらのサイトを参考にしました。

GeForce GTX 1080のVideo BIOS書き換え | PCパーツ海外情報

なお、nvflashのコマンドはnvflash64で実行しています。(64bitOSのため)

f:id:simple-josys:20191214013218p:plain

直りました!!!

半ば諦めていただけにめちゃくちゃ嬉しい!

Windows 1909を使える喜び!!

最新版を使用できる安心感は違いますね。

何が原因だったのか

解決した時点で満足してしまい、根拠を探していないので妄想です。

  • グラボのBIOSがカスタマイズされていた
  • Windows 1803から、危険な設定がされたBIOSは弾くよう仕様が変わった

グラボはヤフオクで購入したものなので前所有者がカスタマイズしていたか、そもそもメーカーでOC仕様にチューニングされていた可能性があります。

何度も再インストールした時間を返してほしい/(^o^)\

ついでにGoogle Chromeが真っ黒になった

グラボが直ったと思ったらChromeが真っ黒になるようになってしまいました。

本当にただ真っ黒なだけだったのでSSはありません。

%USERPROFILE%\AppData\Local\Google\Chrome\User Data\ShaderCache

を削除する

ざっくり結論から言うと、上記の方法で解決しました。

グラボのBIOSが変わったから別物として認識されたのかな?わかりません。

 

Chromeのショートカットのリンク先に「--disable-direct-composition」を追加する方法や、ハードウェアアクセラレーションを切る対処方もありましたが、どちらもその場しのぎでしかなく、Google Mapの3Dビューが使えなくなったので論外でした。

今回の件で得た教訓

新品を買おう。