{"id":803,"date":"2017-11-28T16:46:31","date_gmt":"2017-11-28T07:46:31","guid":{"rendered":"https:\/\/www.amano-labo.jp\/pages\/?p=803"},"modified":"2017-12-11T13:13:48","modified_gmt":"2017-12-11T04:13:48","slug":"slack%e3%81%a7%e3%81%ae%e3%83%a1%e3%83%bc%e3%83%ab%e9%80%9a%e7%9f%a5%e3%82%a2%e3%83%97%e3%83%aa%e3%81%ae%e4%bd%9c%e6%88%90%ef%bc%88events-api%e3%81%ae%e5%88%a9%e7%94%a8%e3%81%a8google-apps-script","status":"publish","type":"post","link":"https:\/\/www.amano-labo.jp\/pages\/blog\/803\/","title":{"rendered":"slack\u3067\u306e\u30e1\u30fc\u30eb\u901a\u77e5\u30a2\u30d7\u30ea\u306e\u4f5c\u6210\uff08events api\u306e\u5229\u7528\u3068Google Apps Script\u3067\u306e\u5b9f\u88c5\uff09"},"content":{"rendered":"<div class=\"amano- amano-entity-placement\" id=\"amano-2438095373\"><div id=\"amano-1182263258\"><a href=\"https:\/\/www.amazon.co.jp\/dp\/4274222640\/ref=cm_sw_r_cp_ep_dp_RK1JBb6W0ZSQ5\" aria-label=\"iotbook201809\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809.png\" alt=\"\"  srcset=\"https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809.png 1000w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-300x24.png 300w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-768x61.png 768w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-100x8.png 100w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-150x12.png 150w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-200x16.png 200w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-450x36.png 450w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-600x48.png 600w, https:\/\/www.amano-labo.jp\/pages\/wp-content\/uploads\/2018\/06\/iotbook201809-900x72.png 900w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" width=\"1000\" height=\"80\"   \/><\/a><\/div><\/div><p>2017\/11\/28 : \u7b2c1\u7248<br \/>\n2017\/12\/11 : \u7b2c2\u7248\uff1aDM\u306e\u5834\u5408\u306b\u306f\u9001\u4fe1\u76f8\u624b\u306b\u306e\u307f\u9001\u4ed8\u3059\u308b\u3088\u3046\u306b\u5909\u66f4\u3002\u305d\u306e\u4ed6\u3001\u8a73\u7d30\u306a\u7b87\u6240\u3092\u4fee\u6b63<\/p>\n<p>\u3053\u306e\u8a18\u4e8b\u306e\u5185\u5bb9\u306fslack\u3092\u3001\u79c1\u306e\u3088\u3046\u306a\u30e1\u30fc\u30eb\u4e2d\u5fc3\u306e\u751f\u6d3b\u3092\u9001\u3063\u3066\u3044\u308b\u4eba\u9593\u304c\u4f7f\u3046\u3068\u304d\u306e\u5185\u5bb9\u3067\u3059\u3002<\/p>\n<p>\u4ee5\u524d\u3001outgoing webhook\u3092\u7528\u3044\u305f\u30e1\u30fc\u30eb\u901a\u77e5\u30dc\u30c3\u30c8\u3092\u5b9f\u73fe\u3057\u3066\u3044\u307e\u3057\u305f\u3002slack\u306e\u30e1\u30fc\u30eb\u901a\u77e5\u6a5f\u80fd\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u4f55\u304b\u3068\u30e1\u30fc\u30eb\u3092\u9001\u3089\u306a\u3044\u6761\u4ef6\u304c\u3042\u308b\u3002\u7d30\u304b\u304f\u8a2d\u5b9a\u3092\u5909\u3048\u3066\u3082\u9001\u3089\u306a\u3044\u6761\u4ef6\u304c\u6b8b\u308b\u306e\u3067\u3059\u3002\u30e1\u30f3\u30d0\u30fc\u3082\u30e1\u30fc\u30eb\u30c9\u30ea\u30d6\u30f3\u306a\u5834\u5408\u3001\u5168\u54e1\u306b\u8a2d\u5b9a\u3092\u5909\u3048\u308b\u3088\u3046\u306b\u8aac\u660e\u3059\u308b\u306e\u3082\u9762\u5012\u3067\u3059\u3002\u79c1\u3068\u3057\u3066\u306f\u5e38\u306b\u3059\u3050\u306b\u30e1\u30fc\u30eb\u3067\u901a\u77e5\u3059\u308b\u6a5f\u80fd\u304c\u6b32\u3057\u304b\u3063\u305f\u306e\u3067\u3059\u3002<\/p>\n<p>\u65b0\u3057\u3044workspace\u7528\u306b\u904e\u53bb\u306e\u8cc7\u7523\u3092\u518d\u5229\u7528\u3057\u3088\u3046\u3068\u3057\u305f\u3068\u3053\u308d\u3001outgoing webhook\u306flegacy\u6271\u3044\u306b\u306a\u3063\u3066\u3044\u3066\u3001\u65b0\u898f\u306b\u767b\u9332\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\u3082\u3057\u304b\u3057\u305f\u3089\u65b0\u3057\u304f\u767b\u9332\u3059\u308b\u65b9\u6cd5\u3082\u3042\u308b\u306e\u304b\u3082\u3057\u308c\u307e\u305b\u3093\u304c\u3001\u305b\u3063\u304b\u304f\u306a\u306e\u3067\u65b0\u3057\u3044events api\u3092\u8a66\u3057\u3066\u307f\u308b\u3053\u3068\u3068\u3057\u307e\u3057\u305f\u3002<\/p>\n<p>\u3053\u3053\u3067\u306f\u5358\u7d14\u306b\u300c\u8ab0\u304c\u300d\u300c\u4f55\u3068\u66f8\u3044\u305f\u304b\u300d\u3092\u30e1\u30f3\u30d0\u30fc\u5168\u54e1\u306b\u30e1\u30fc\u30eb\u3067\u901a\u77e5\u3059\u308b\u3053\u3068\u3068\u3057\u307e\u3059\u3002<\/p>\n<ol>\n<li>\u300chttps:\/\/api.slack.com\/apps\/\u300d\u304b\u3089\u65b0\u898f\u30a2\u30d7\u30ea\u3092\u4f5c\u6210<\/li>\n<li>\u300cEvents API(Event Subscriptions)\u300d\u304b\u3089enable\u3068\u3057\u3001\u4ee5\u4e0b\u3092\u8ffd\u52a0\n<ul>\n<li>file_comment_added<\/li>\n<li>file_created<\/li>\n<li>im_created<\/li>\n<li>message.channels<\/li>\n<li>message.groups<\/li>\n<li>message.im<\/li>\n<li>message.mpim<\/li>\n<\/ul>\n<\/li>\n<li>\u300cRequest URL\u300d\u306f\u5f8c\u8ff0\u306eGoogle Apps Script\u306eWeb URL\u3092\u6307\u5b9a<\/li>\n<li>\u300cOAuth &amp; Permissions\u300d\u3067\u4ee5\u4e0b\u306e\u4e8c\u3064\u306eScope\u3092\u8ffd\u52a0\n<ul>\n<li><span class=\"subtle_silver\">users:read<\/span><\/li>\n<li><span class=\"subtle_silver\">users:read.email<\/span><\/li>\n<\/ul>\n<\/li>\n<li>\u300cOAuth Access Token\u300d\u306e\u5185\u5bb9\u3092\u30e1\u30e2<\/li>\n<li>Gdrive\u3067\u9069\u5f53\u306a\u30d5\u30a9\u30eb\u30c0\u30fc\u306bSpreadsheet\u3092\u65b0\u898f\u4f5c\u6210\uff08\u5c65\u6b74\u4fdd\u7ba1\u7528\uff09<\/li>\n<li>\u30c4\u30fc\u30eb\u2192\u30b9\u30af\u30ea\u30d7\u30c8\u30a8\u30c7\u30a3\u30bf\u30fc\n<ul>\n<li>\u4ee5\u4e0b\u306e\u5185\u5bb9\u3092\u4f5c\u6210<\/li>\n<li>\u300cxoxp-??????????\u300d\u306e\u90e8\u5206\u306f\u4e0a\u306e\u300cOAuth Access Token\u300d\u306e\u30e1\u30e2\u5185\u5bb9\u3068\u3059\u308b<\/li>\n<\/ul>\n<\/li>\n<li>\u516c\u958b\u2192Web\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3068\u3057\u3066\u5c0e\u5165\n<ul>\n<li>\u3053\u3053\u3067\u5f97\u3089\u308c\u305fURL\u30923\u306eURL\u306b\u3059\u308b<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<pre class=\"lang:default decode:true\">var SLACK_TOKEN = \"xoxp-??????????\";\r\n\r\nvar userList = {};\r\nvar nameList = {};\r\nvar ss = SpreadsheetApp.getActiveSpreadsheet();\r\nvar sheetLog = ss.getSheets()[0];\r\nvar now = null;\r\n\r\nfunction doGet(e) {\r\n  doPost(e);\r\n}\r\n\r\nfunction doPost(e) {\r\n  try {\r\n    now = new Date();\r\n    \r\n\tvar values = JSON.parse(e.postData.contents);\r\n\r\n    \/\/ sheetLog.appendRow([ now, e ]);\r\n    \/\/ sheetLog.appendRow([ now, e.postData ]);\r\n    sheetLog.appendRow([ now, values ]);\r\n    \r\n    if (values.type == \"url_verification\") {\r\n      sheetLog.appendRow([now, 'url_verification', values.type, values.token, values.challenge ]);\r\n      return ContentService.createTextOutput(JSON.stringify(values.challenge)).setMimeType(ContentService.MimeType.TEXT);\r\n\r\n    } else if (values.type == \"event_callback\") {\r\n      if (values.event.type == \"message\") {\r\n        getMails();\r\n        \r\n        var text = values.event.text;\r\n        \r\n        if (text != undefined) {\r\n          var username = userList[values.event.user];\r\n          var userRealname = nameList[values.event.user];\r\n          var channelName = getChannel(values.event.channel);\r\n          var wsName = getWS();\r\n          \r\n          var toStr = \"\";\r\n          if (channelName != null) {\r\n            \/\/ channel\u3078\u306e\u6295\u7a3f\r\n            for (var key in userList) {\r\n              if (toStr != \"\") {\r\n                toStr = toStr + \",\";\r\n              }\r\n              toStr = toStr + userList[key];\r\n            }\r\n          } else {\r\n            \/\/ GRP\u540d\u304c\u306a\u3044=DM?\r\n            \/\/ sheetLog.appendRow([ now, 'channel null', values.event.channel ]);\r\n            var uid = getDMTargetUID(values.event.channel);\r\n            \r\n            if (uid != null) {\r\n              channelName = 'Direct Message';\r\n              toStr = userList[uid];\r\n            } else {\r\n              channelName = '\u30b5\u30dd\u30fc\u30c8\u5916\u30e1\u30c3\u30bb\u30fc\u30b8';\r\n              text = '\u30b5\u30dd\u30fc\u30c8\u5916\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3067\u3057\u305f\u3002';\r\n            }\r\n          }\r\n          \r\n          sheetLog.appendRow([now, 'sendmail', toStr]);\r\n          MailApp.sendEmail(\r\n            null,\r\n            'notify slack(' + wsName + ') new text by ' + username,\r\n            userRealname + '(' + username + ') says\\n\\n ' + text + '\\n\\n'\r\n            + 'at ' + channelName + ' channel, ' + wsName + '\\n\\n',\r\n            {bcc : toStr }\r\n          );\r\n        } else {\r\n          sheetLog.appendRow([now, 'same pre\\ivious' ]);\r\n        }\r\n      }\r\n    }\r\n  } catch (ee) {\r\n    sheetLog.appendRow([now, ee ]);\r\n  }\r\n}\r\n\r\nfunction getMails() {\r\n  var response = UrlFetchApp.fetch(\"https:\/\/slack.com\/api\/users.list?token=\" + SLACK_TOKEN);\r\n  \r\n  var content = response.getContentText(\"UTF-8\");\r\n  var values = JSON.parse(content);\r\n  \r\n  \/\/ Logger.log(values);\r\n  \/\/ sheetLog.appendRow([ now, 'getMails', values ]);\r\n  \r\n  userList = {};\r\n  nameList = {};\r\n  for (var i = 0; i &lt; values['members'].length; i++) {\r\n    try {\r\n      var id = values['members'][i]['id'];\r\n      var ma = values['members'][i]['profile']['email'];\r\n      if (ma != undefined) {\r\n        userList[id] = ma;\r\n        nameList[id] = values['members'][i]['profile']['real_name'];\r\n      }\r\n    } catch (e1) {\r\n      ;\r\n    }\r\n  }\r\n}\r\n\r\nfunction getChannel(cid) {\r\n  var channelName = null;\r\n  \r\n  var response = UrlFetchApp.fetch(\"https:\/\/slack.com\/api\/channels.list?token=\" + SLACK_TOKEN);\r\n  \r\n  var content = response.getContentText(\"UTF-8\");\r\n  var values = JSON.parse(content);\r\n  \r\n  \/\/ Logger.log(values);\r\n  \/\/ sheetLog.appendRow([ now, 'getChannel', values['channels'] ]);\r\n  \r\n  for (var i = 0; i &lt; values['channels'].length; i++) {\r\n    try {\r\n      var id = values['channels'][i]['id'];\r\n      if (id == cid) {\r\n        var ma = values['channels'][i]['name_normalized'];\r\n        if (ma != undefined) {\r\n          channelName = ma;\r\n          break;\r\n        }\r\n      }\r\n    } catch (e1) {\r\n      ;\r\n    }\r\n  }\r\n  \r\n  \/\/ sheetLog.appendRow([ now, 'getChannel', cid, channelName ]);\r\n  \r\n  return channelName;\r\n}\r\n\r\nfunction getDMTargetUID(did) {\r\n  var uid = null;\r\n  \r\n  var response = UrlFetchApp.fetch(\"https:\/\/slack.com\/api\/im.list?token=\" + SLACK_TOKEN);\r\n  \r\n  var content = response.getContentText(\"UTF-8\");\r\n  var values = JSON.parse(content);\r\n  \r\n  \/\/ Logger.log(values);\r\n  \/\/ sheetLog.appendRow([ now, 'getDMTargetUID', did, values['ims'] ]);\r\n  \r\n  for (var i = 0; i &lt; values['ims'].length; i++) {\r\n    try {\r\n      \/\/ sheetLog.appendRow([ now, ''+values['ims'][i] ]);\r\n      var id = values['ims'][i]['id'];\r\n      if (id == did) {\r\n        uid = values['ims'][i]['user'];\r\n        \/\/ sheetLog.appendRow([ now, id, uid ]);\r\n        if (uid != undefined) {\r\n          break;\r\n        }\r\n      }\r\n    } catch (e1) {\r\n      ;\r\n    }\r\n  }\r\n  \r\n  \/\/ sheetLog.appendRow([ now, did, uid ]);\r\n  \r\n  return uid;\r\n}\r\n\r\n\r\nfunction getWS() {\r\n  var response = UrlFetchApp.fetch(\"https:\/\/slack.com\/api\/team.info?token=\" + SLACK_TOKEN);\r\n  \r\n  var content = response.getContentText(\"UTF-8\");\r\n  var values = JSON.parse(content);\r\n  \r\n  return values['team']['name'];\r\n}\r\n<\/pre>\n<p>\u904e\u53bb\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u306fSpreadsheet\u306b\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u30ea\u30b9\u30c8\u5316\u3057\u3066\u7528\u610f\u3057\u3066\u3044\u307e\u3057\u305f\u304c\u3001\u4eca\u56de\u306fslack api\u3092\u901a\u3058\u3066\u30e1\u30f3\u30d0\u30fc\u306e\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3082\u53d6\u5f97\u3057\u3066\u3044\u307e\u3059\u3002\u3053\u308c\u306b\u306f\u4e00\u9577\u4e00\u77ed\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>2017\/11\/28 : \u7b2c1\u7248 2017\/12\/11 : \u7b2c2\u7248\uff1aDM\u306e\u5834\u5408\u306b\u306f\u9001\u4fe1\u76f8\u624b\u306b\u306e\u307f\u9001\u4ed8\u3059\u308b\u3088\u3046\u306b\u5909\u66f4\u3002\u305d\u306e\u4ed6\u3001\u8a73\u7d30\u306a\u7b87\u6240\u3092\u4fee\u6b63 \u3053\u306e\u8a18\u4e8b\u306e\u5185\u5bb9\u306fslack\u3092\u3001\u79c1\u306e\u3088\u3046\u306a\u30e1\u30fc\u30eb\u4e2d\u5fc3\u306e\u751f\u6d3b\u3092\u9001\u3063\u3066\u3044\u308b\u4eba\u9593\u304c\u4f7f\u3046 <a class=\"more-link\" href=\"https:\/\/www.amano-labo.jp\/pages\/blog\/803\/\">\u7d9a\u304d\u3092\u8aad\u3080\u2026<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[6,2,4],"tags":[31,19,28],"class_list":["post-803","post","type-post","status-publish","format-standard","hentry","category-software","category-blog","category-tips","tag-google-apps-script","tag-javascript","tag-slack"],"_links":{"self":[{"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/posts\/803","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/comments?post=803"}],"version-history":[{"count":0,"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/posts\/803\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/media?parent=803"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/categories?post=803"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.amano-labo.jp\/pages\/wp-json\/wp\/v2\/tags?post=803"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}