Last active
June 3, 2021 14:37
-
-
Save woodwardtw/a6ce4e271abd07ec22b969187aa7ea1f to your computer and use it in GitHub Desktop.
updated/expanded dlinq slack app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const { App } = require('@slack/bolt'); | |
| const WPAPI = require( 'wpapi' );//add in http://wp-api.org/node-wpapi | |
| // Initializes your app with your bot token and signing secret | |
| const app = new App({ | |
| token: process.env.SLACK_BOT_TOKEN, | |
| signingSecret: process.env.SLACK_SIGNING_SECRET | |
| }); | |
| app.command('/courseupdate', async ({ command, ack, body, client }) => { | |
| // Acknowledge the command request | |
| await ack(); | |
| try { | |
| // Call views.open with the built-in client | |
| const result = await client.views.open({ | |
| // Pass a valid trigger_id within 3 seconds of receiving it | |
| trigger_id: body.trigger_id, | |
| // View payload | |
| view: { | |
| type: 'modal', | |
| // View identifier | |
| callback_id: 'course-submit', | |
| title: { | |
| type: 'plain_text', | |
| text: 'Course Update' | |
| }, | |
| blocks: [{ | |
| type: "input", | |
| block_id: 'course_selection', | |
| element: { | |
| type: "static_select", | |
| placeholder: { | |
| type: "plain_text", | |
| text: "Select your course", | |
| emoji: true | |
| }, | |
| options: [ | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "EDUC 8502: Principles & Practices 1", | |
| emoji: true | |
| }, | |
| value: "educ-8502-principles-practices-1"//20 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "ICC Global Leadership", | |
| emoji: true | |
| }, | |
| value: "icc-global-leadership"//9 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "Japanese Ethnography", | |
| emoji: true | |
| }, | |
| value: "japanese-ethnography-as-a-window-to-japanese-language-and-society"//10 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "Japanese Introduction to Japanese Pedagogy", | |
| emoji: true | |
| }, | |
| value: "japanese-introduction-to-japanese-pedagogy"//11 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "LING 8500: Language Analysis", | |
| emoji: true | |
| }, | |
| value: "ling-8500-language-analysis"//17 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "LING 8510: Intro to Sociolinguistics", | |
| emoji: true | |
| }, | |
| value: "ling-8510-intro-to-sociolinguistics"//19 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "LING 8630: SLA", | |
| emoji: true | |
| }, | |
| value: "ling-8630-sla"//18 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "Program Management", | |
| emoji: true | |
| }, | |
| value: "program-management"//12 | |
| }, | |
| { | |
| text: { | |
| type: "plain_text", | |
| text: "Software Internationalization and Localization", | |
| emoji: true | |
| }, | |
| value: "software-internationalization-and-localization"//13 | |
| } | |
| ], | |
| action_id: "course_input" | |
| }, | |
| label: { | |
| type: "plain_text", | |
| text: "Course selection", | |
| emoji: true | |
| } | |
| }, | |
| { | |
| type: 'input', | |
| block_id: 'good_stuff', | |
| optional: true, | |
| label: { | |
| type: 'plain_text', | |
| text: 'What is going well this week?' | |
| }, | |
| element: { | |
| type: 'plain_text_input', | |
| action_id: 'good_input', | |
| multiline: true, | |
| } | |
| },{ | |
| type: 'input', | |
| block_id: 'flag_stuff', | |
| optional: true, | |
| label: { | |
| type: 'plain_text', | |
| text: 'Yellow or red flags this week?' | |
| }, | |
| element: { | |
| type: 'plain_text_input', | |
| action_id: 'flag_input', | |
| multiline: true | |
| } | |
| },{ | |
| type: 'input', | |
| block_id: 'other_stuff', | |
| optional: true, | |
| label: { | |
| type: 'plain_text', | |
| text: 'Anything else to share?' | |
| }, | |
| element: { | |
| type: 'plain_text_input', | |
| action_id: 'other_input', | |
| multiline: true | |
| } | |
| } | |
| ], | |
| submit: { | |
| type: 'plain_text', | |
| text: 'Submit', | |
| } | |
| } | |
| }); | |
| //console.log(JSON.stringify(result)); | |
| } | |
| catch (error) { | |
| console.error(error); | |
| } | |
| }); | |
| //update | |
| app.view('course-submit', async ({ ack, body, view, client }) => { | |
| // Acknowledge the action | |
| await ack(); | |
| //console.log(JSON.stringify(body));//see the data getting passed | |
| let msg = ''; | |
| const user = body['user']['id']; | |
| const results = await createWpUpdate(body['user']['username'],body); | |
| if (results > 0){ | |
| msg = 'Your update was successful. https://media.giphy.com/media/Ry3Yl9TQlUAxy/giphy.gif' | |
| } else { | |
| msg = 'I am a failure but I do not know why.' | |
| } | |
| //message the user | |
| try { | |
| await client.chat.postMessage({ | |
| channel: user, | |
| text: msg | |
| }); | |
| } | |
| catch (error){ | |
| console.error(error); | |
| } | |
| }); | |
| //create update for project management site specific to a course | |
| function createWpUpdate(slackuser, body){ | |
| const values = body.view.state.values; | |
| let good = values.good_stuff.good_input.value; | |
| let flag = values.flag_stuff.flag_input.value; | |
| let other = values.other_stuff.other_input.value; | |
| let course = values.course_selection.course_input.selected_option.value;//easy to miss selected_option | |
| let courseId = courseTagToID(course); | |
| console.log(courseId); | |
| var wp = new WPAPI({ | |
| endpoint: 'https://experiments.middcreate.net/pm/wp-json', | |
| // This assumes you are using basic auth, as described further below | |
| username: process.env.WP_USER, | |
| password: process.env.WP_PASS | |
| }); | |
| var user = process.env.WP_USER; | |
| //**************DONT FORGET BASIC AUTH PLUGIN!!!!!!!https://github.com/WP-API/Basic-Auth | |
| //establish route for custom post type update ***************** from https://github.com/WP-API/node-wpapi/issues/275 | |
| const namespace = 'wp/v2'; | |
| const updateRoute = '/update/'; | |
| wp.update = wp.registerRoute(namespace, updateRoute); | |
| //date | |
| const currentDate = new Date(); | |
| const currentDayOfMonth = currentDate.getDate(); | |
| const currentMonth = currentDate.getMonth(); // Be careful! January is 0, not 1 | |
| const currentYear = currentDate.getFullYear(); | |
| const dateString = currentDayOfMonth + "-" + (currentMonth + 1) + "-" + currentYear; | |
| try { | |
| wp.update().create({ //leave as post instead of update if just regular post | |
| // "title" and "content" are the only required properties | |
| title: slackuser + ' via slackbot on ' + dateString, | |
| content: 'nothing to see here', | |
| post_type: 'update', | |
| meta: { | |
| going_well: good,//tied to defining them on the WP side w register_meta | |
| flags: flag, | |
| else: other | |
| }, | |
| tags: [ courseId ], | |
| // Post will be created as a draft by default if a specific "status" | |
| // is not specified | |
| status: 'publish' | |
| }).then(function( response ) { | |
| // "response" will hold all properties of your newly-created post, | |
| // including the unique `id` the post was assigned on creation | |
| console.log( response.id ); | |
| var post_id = response.id; | |
| }) | |
| return true; | |
| } catch (error){ | |
| console.log(error) | |
| return false; | |
| } | |
| } | |
| function courseTagToID(course){ | |
| let courses = { | |
| 'educ-8502-principles-practices-1': 20, | |
| 'ling-8500-language-analysis' : 17, | |
| 'ling-8510-intro-to-sociolinguistics' : 19, | |
| 'ling-8630-sla' : 18, | |
| 'icc-global-leadership': 7, | |
| 'japanese-ethnography-as-a-window-to-japanese-language-and-society': 10, | |
| 'japanese-introduction-to-japanese-pedagogy': 11, | |
| 'program-management': 13, | |
| 'software-internationalization-and-localization': 14, | |
| }; | |
| if (courses[course]){ | |
| return courses[course];//remember the issue with hyphens in json | |
| } else { | |
| return 16; | |
| } | |
| } | |
| //say hi for no reason | |
| app.message(':wave:', async ({ message, say }) => { | |
| await say(`Hello, <@${message.user}>`); | |
| }); | |
| //shortcut to push a message as a post to dlinq site | |
| app.shortcut('dlinq_post', async ({ shortcut, ack, client, message }) => { | |
| try { | |
| // Acknowledge shortcut request | |
| await ack(); | |
| //console.log('short******'); | |
| //console.log(shortcut); | |
| //console.log(shortcut.message.text) | |
| //console.log(JSON.stringify(shortcut.message.attachments[0])) | |
| const postTitle = postTitleMaker(shortcut.message.attachments[0]); | |
| // Call the views.open method using one of the built-in WebClients | |
| const result = await client.views.open({ | |
| trigger_id: shortcut.trigger_id, | |
| view: { | |
| type: "modal", | |
| callback_id: 'dlinq-post', | |
| title: { | |
| type: "plain_text", | |
| text: "DLINQ Web Poster" | |
| }, | |
| close: { | |
| type: "plain_text", | |
| text: "Close" | |
| }, | |
| blocks: [ | |
| { | |
| type: "section", | |
| text: { | |
| type: "mrkdwn", | |
| text: "This will post the message to the DLINQ website. You good with that?" | |
| } | |
| }, | |
| { | |
| type: "input", | |
| block_id: 'post_title', | |
| element: { | |
| type: "plain_text_input", | |
| action_id: "post_title", | |
| initial_value: postTitle | |
| }, | |
| label: { | |
| type: "plain_text", | |
| text: "Post title", | |
| emoji: true | |
| } | |
| }, | |
| { | |
| type: 'input', | |
| block_id: 'main_post', | |
| optional: true, | |
| label: { | |
| type: 'plain_text', | |
| text: 'Add additional context or alter the original text.' | |
| }, | |
| element: { | |
| type: 'plain_text_input', | |
| action_id: 'main_post', | |
| multiline: true, | |
| initial_value: shortcut.message.text + postBodyMaker(shortcut.message.attachments[0]) | |
| } | |
| } | |
| ], | |
| submit: { | |
| type: 'plain_text', | |
| text: 'Submit', | |
| } | |
| } | |
| }); | |
| // console.log(JSON.stringify(result));//see the data getting passed | |
| } | |
| catch (error) { | |
| console.error(error); | |
| } | |
| }); | |
| //acknowledge dlinq post submission | |
| app.view('dlinq-post', async ({ ack, body, view, client }) => { | |
| // Acknowledge the action | |
| await ack(); | |
| console.log(JSON.stringify(body));//see the data getting passed | |
| let msg = ''; | |
| const user = body['user']['id']; | |
| const results = await createDlinqPost(body['user']['username'],body); | |
| if (results){ | |
| msg = '🎉Your post was successful. You are a champion!🎉 Let this victory be one of many today!' | |
| } else { | |
| msg = 'It is my fault. I am a failure but I do not know why.' | |
| } | |
| //message the user | |
| try { | |
| await client.chat.postMessage({ | |
| channel: user, | |
| text: msg | |
| }); | |
| } | |
| catch (error){ | |
| console.error(error); | |
| } | |
| }); | |
| //makes post title for dlinq post | |
| function postTitleMaker(attachments){ | |
| var serviceName = '' | |
| var articleTitle = 'An interesting article' | |
| if(attachments){ | |
| if (attachments.service_name){ | |
| serviceName = ' from ' + attachments.service_name; | |
| } | |
| if (attachments.title){ | |
| articleTitle = attachments.title; | |
| } | |
| return articleTitle + serviceName; | |
| } else { | |
| return 'Please make an interesting title' | |
| } | |
| } | |
| //creates post body for dlinq post | |
| function postBodyMaker(attachments){ | |
| //console.log(attachments) | |
| var link = '' | |
| var author = '' | |
| var thumb = '' | |
| var text = '' | |
| if (attachments.title_link){ | |
| link = attachments.title_link; | |
| } | |
| if (attachments.author_name){ | |
| author = attachments.author_name; | |
| } | |
| if (attachments.text){ | |
| text = attachments.text; | |
| } | |
| if (attachments.image_url || attachments.thumb_url){ | |
| if(attachments.image_url){ | |
| var imgUrl = attachments.image_url; | |
| } else { | |
| var imgUrl = attachments.thumb_url; | |
| } | |
| thumb = `<a href="${link}"><img src="${imgUrl}" alt="${text}"></a>`; | |
| } | |
| return `${thumb}<blockquote><a href="${link}">${text}</a><br>${author}</blockquote>`; | |
| } | |
| function createDlinqPost(slackuser, body){ | |
| const values = body.view.state.values; | |
| const postTitle = values.post_title.post_title.value; | |
| const postBody = values.main_post.main_post.value; | |
| var wp = new WPAPI({ | |
| endpoint: 'https://experiments.middcreate.net/slack/wp-json', | |
| // This assumes you are using basic auth, as described further below | |
| username: process.env.WP_USER, | |
| password: process.env.WP_PASS | |
| }); | |
| // console.log(process.env.WP_USER); | |
| // console.log(process.env.WP_PASS); | |
| //var user = process.env.WP_USER; | |
| //**************DONT FORGET BASIC AUTH PLUGIN!!!!!!!https://github.com/WP-API/Basic-Auth | |
| try { | |
| wp.posts().create({ //leave as post instead of update if just regular post | |
| // "title" and "content" are the only required properties | |
| title: postTitle , | |
| content: postBody, | |
| //tags: [ courseId ], | |
| // Post will be created as a draft by default if a specific "status" | |
| // is not specified | |
| status: 'publish' | |
| }).then(function( response ) { | |
| // "response" will hold all properties of your newly-created post, | |
| // including the unique `id` the post was assigned on creation | |
| //console.log(response); | |
| console.log(response.id ); | |
| }) | |
| return true; | |
| } | |
| catch (error){ | |
| return false; | |
| } | |
| } | |
| (async () => { | |
| // Start your app | |
| await app.start(process.env.PORT || 3000); | |
| console.log('⚡️ Bolt app is running!'); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment