bolt-js icon indicating copy to clipboard operation
bolt-js copied to clipboard

How do i update "messages_tab_read_only_enabled" to true/false programmatically

Open HarikaKonda01 opened this issue 1 year ago • 4 comments

Question

My app initially would have "messages_tab_read_only_enabled" to true making users unable to message to app, but when an action is done in app home e.g. after submitting a form, I want to enable the messages for the app making "message_tab_read_only_enabled" to false. I have checked the web apis and found that apps.manifest.update would help, but from here https://github.com/slackapi/node-slack-sdk/issues/1622, i have found that we cant create app configuration tokens programmatically. So, is there any other way to develop this feature when it is a workspace install !? and how to do it when it is an enterprise organization install!?

Below are my slack app specifications

@slack/bolt version

^3.17.1

Your App and Receiver Configuration

const app = new App({
  // logLevel: LogLevel.DEBUG,
  signingSecret: process.env.SLACK_SIGNING_SECRET,
  clientId: process.env.SLACK_CLIENT_ID,
  clientSecret: process.env.SLACK_CLIENT_SECRET,
  stateSecret: "example-code",
  // customRoutes: customRoutes.customRoutes, // can add custom routes for installation purpose
  scopes: botSopes,
  redirectUri: oauthRedirect,
  installerOptions: {
    // stateVerification: false,
    redirectUriPath: "/slack/oauth_redirect",
    // directInstall: true,
  },
  installationStore: {
    storeInstallation: async (installation) => {
      if (
        installation.isEnterpriseInstall &&
        installation.enterprise !== undefined
      ) {
        return orgAuth.saveUserOrgInstall(installation);
      }
      if (installation.team !== undefined) {
        return workspaceAuth.saveUserWorkspaceInstall(installation);
      }
      throw new Error("Failed saving installation data to installationStore");
    },
    fetchInstallation: async (installQuery) => {
      if (
        installQuery.isEnterpriseInstall &&
        installQuery.enterpriseId !== undefined
      ) {
        return findUser(installQuery.enterpriseId);
      }
      if (installQuery.teamId !== undefined) {
        return findUser(installQuery.teamId);
      }
      throw new Error("Failed fetching installation");
    },
  },
});

Node.js runtime version

v18.18.0

HarikaKonda01 avatar Jun 05 '24 18:06 HarikaKonda01

Hi @HarikaKonda01, thanks for asking the question.

i have found that we cant create app configuration tokens programmatically

Unfortunately, there is no way to achieve this. Once you create a token, you can save it either as an env variable or in a datastore.

By the way, if you're trying to customize the message tab behavior per workspace, it doesn't work in the way. When you enable the tab within the app manifest, the change will affect all installed workspaces and organizations. Therefore, I'd suggest enabling the tab by default plus responding to any incoming messages from a user by saying "Hey, you need to configure this app first. Click this button to complete the initial setup!" or something similar.

I hope this helps.

seratch avatar Jun 06 '24 04:06 seratch

@seratch , Thanks for clarifying my question. This helped a lot. Thank you

HarikaKonda01 avatar Jun 10 '24 14:06 HarikaKonda01

@seratch , I have a bit progress in my app development here. I have added aws lambda receiver and running the app locally with severless offline and facing bit issue in opening one of my modal. Initially I have an modal where I submit details. On submit, I am opening another modal first and updating that modal with data later. After that, Im updating the app home view. But after i added receiver and serverless, I am facing two issues:

  1. Sometimes I get expired trigger Id error
  2. The second modal doesnt even open and giving this error on the modal image I have check the logs, of views.open and views.update, the response looks fine Is there anything im doing wrong here. Here is my code
const connectViewCallback = async ({ ack, body, client, view, logger }) => {
  try {
    await ack();
    const { input_tenantKey = null, input_tenantUrl = null } =
      view.state.values;
    const TenantUrl = input_tenantUrl?.action_input_tenantUrl.value;
    const ApiKey = input_tenantKey?.action_input_tenantKey.value);
    viewConnectStatus.trigger_id = body.trigger_id;
    viewConnectStatus.view.blocks[2].elements[0].elements[3].text =
      TenantUrl;
    const result = await client.views.open(viewConnectStatus);
    delete viewConnectStatus.trigger_id;
    viewConnectStatus.view_id = result.view.id;
    // viewConnectStatus.hash = body.view.hash;
    const verify = await verifyConnection(TenantUrl, ApiKey);
    const connection = verify ? "Successful" : "Unsuccessful";
    viewConnectStatus.view.blocks[2].elements[0].elements[1].text = `${connection}\n`;
    const res = await client.views.update(viewConnectStatus);
    console.log(res);
    if(verify) {
      const data = {
        tenant : TenantUrl,
        apiKey : ApiKey,
      }
      await updateTeamInfo(data, body.team.id);
      const homeView = appHomeView(body.user.id);
      const dividerObj = { type: "divider" };
      const tenantObj = {
        type: "section",
        text: {
          type: "mrkdwn",
          text: `Your workspace is connected to ${TenantUrl}. If you wish to change it please connect with your new credentials.`,
        }}
      homeView.blocks.splice(2,0,tenantObj,dividerObj);
      await client.views.update({ external_id: body.user.id+ "app_home_block", view: homeView});
      return;
    }
  } catch (err) {
    logger.error(err);
    return ack(err);
  }
};

and here is my logger response

[DEBUG]  bolt-app No conversation ID for incoming event
[DEBUG]  web-api:WebClient:1 apiCall('views.open') start
[DEBUG]  web-api:WebClient:1 http request url: https://slack.com/api/views.open
[DEBUG]  web-api:WebClient:1 http request body: {"team_id":"T06P3FANVFU","view":"{\"type\":\"modal\",\"callback_id\":\"view_verify\",\"title\":{\"type\":\"plain_text\",\"text\":\"BotApp\"},\"blocks\":[{\"type\":\"header\",\"block_id\":\"header_verify_modal\",\"text\":{\"type\":\"plain_text\",\"text\":\"BotApp Connection Status\"}},{\"type\":\"divider\"},{\"type\":\"rich_text\",\"elements\":[{\"type\":\"rich_text_section\",\"elements\":[{\"type\":\"text\",\"text\":\"Connection: \",\"style\":{\"bold\":true}},{\"type\":\"text\",\"text\":\" \"},{\"type\":\"text\",\"text\":\"Tenant: \",\"style\":{\"bold\":true}},{\"type\":\"text\",\"text\":\"https://testtenant.com\"}]}]}],\"close\":{\"type\":\"plain_text\",\"text\":\"Close\"}}","trigger_id":"7260234216357.6785520777538.a7cfe27eeeec90af1173bbd2ec57f214"}
[DEBUG]  web-api:WebClient:1 http request headers: {}
Connected to MongoDB
[DEBUG]  web-api:WebClient:1 http response received
[DEBUG]  web-api:WebClient:1 http request result: {"ok":true,"view":{"id":"V077R0NRD35","team_id":"T06P3FANVFU","type":"modal","blocks":[{"type":"header","block_id":"header_verify_modal","text":{"type":"plain_text","text":"BotApp Connection Status","emoji":true}},{"type":"divider","block_id":"jHooh"},{"type":"rich_text","block_id":"+U7Ee","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"Connection: ","style":{"bold":true}},{"type":"text","text":" "},{"type":"text","text":"Tenant: ","style":{"bold":true}},{"type":"text","text":"https://testtenant.com"}]}]}],"private_metadata":"","callback_id":"view_verify","state":{"values":{}},"hash":"1718184114.Usw1Lq7V","title":{"type":"plain_text","text":"BotApp","emoji":true},"clear_on_close":false,"notify_on_close":false,"close":{"type":"plain_text","text":"Close","emoji":true},"submit":null,"previous_view_id":null,"root_view_id":"V077R0NRD35","app_id":"A06UFRZN9M5","external_id":"","app_installed_team_id":"T06P3FANVFU","bot_id":"B06UWD4QV6W"},"response_metadata":{"scopes":["calls:write","channels:read","im:history","commands","chat:write","channels:history","users:read.email","users:read"]}}
[DEBUG]  web-api:WebClient:1 apiCall('views.open') end
Connected
[DEBUG]  web-api:WebClient:1 apiCall('views.update') start
[DEBUG]  web-api:WebClient:1 http request url: https://slack.com/api/views.update
[DEBUG]  web-api:WebClient:1 http request body: {"team_id":"T06P3FANVFU","view":"{\"type\":\"modal\",\"callback_id\":\"view_verify\",\"title\":{\"type\":\"plain_text\",\"text\":\"BotApp\"},\"blocks\":[{\"type\":\"header\",\"block_id\":\"header_verify_modal\",\"text\":{\"type\":\"plain_text\",\"text\":\"BotApp Connection Status\"}},{\"type\":\"divider\"},{\"type\":\"rich_text\",\"elements\":[{\"type\":\"rich_text_section\",\"elements\":[{\"type\":\"text\",\"text\":\"Connection: \",\"style\":{\"bold\":true}},{\"type\":\"text\",\"text\":\"Successful\\n\"},{\"type\":\"text\",\"text\":\"Tenant: \",\"style\":{\"bold\":true}},{\"type\":\"text\",\"text\":\"https://testtenant.com\"}]}]}],\"close\":{\"type\":\"plain_text\",\"text\":\"Close\"}}","view_id":"V077R0NRD35"}
[DEBUG]  web-api:WebClient:1 http request headers: {}
[DEBUG]  web-api:WebClient:1 http response received
[DEBUG]  web-api:WebClient:1 http request result: {"ok":true,"view":{"id":"V077R0NRD35","team_id":"T06P3FANVFU","type":"modal","blocks":[{"type":"header","block_id":"header_verify_modal","text":{"type":"plain_text","text":"BotApp Connection Status","emoji":true}},{"type":"divider","block_id":"njX2F"},{"type":"rich_text","block_id":"XabS5","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"Connection: ","style":{"bold":true}},{"type":"text","text":"Successful\n"},{"type":"text","text":"Tenant: ","style":{"bold":true}},{"type":"text","text":"https://testtenant.com"}]}]}],"private_metadata":"","callback_id":"view_verify","state":{"values":{}},"hash":"1718184115.abtSg3Uf","title":{"type":"plain_text","text":"BotApp","emoji":true},"clear_on_close":false,"notify_on_close":false,"close":{"type":"plain_text","text":"Close","emoji":true},"submit":null,"previous_view_id":null,"root_view_id":"V077R0NRD35","app_id":"A06UFRZN9M5","external_id":"","app_installed_team_id":"T06P3FANVFU","bot_id":"B06UWD4QV6W"},"response_metadata":{"scopes":["calls:write","channels:read","im:history","commands","chat:write","channels:history","users:read.email","users:read"]}}
[DEBUG]  web-api:WebClient:1 apiCall('views.update') end
[DEBUG]  web-api:WebClient:1 apiCall('views.update') start
[DEBUG]  web-api:WebClient:1 http request url: https://slack.com/api/views.update
[DEBUG]  web-api:WebClient:1 http request body: {"team_id":"T06P3FANVFU","external_id":"U06P0HP9Y9Kapp_home_block","view":"{\"type\":\"home\",\"callback_id\":\"home_view\",\"external_id\":\"U06P0HP9Y9Kapp_home_block\",\"blocks\":[{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"*Welcome to BotApp Bot, <@U06P0HP9Y9K> *\"}},{\"type\":\"divider\"},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"Your workspace is connected to https://testtenant.com. If you wish to change it please connect with your new credentials.\"}},{\"type\":\"divider\"},{\"type\":\"section\",\"text\":{\"type\":\"mrkdwn\",\"text\":\"This is BotApp Bot App. As an admin, please configure the BotApp details here. We will integrate that tenant to this slack app.\"}},{\"type\":\"actions\",\"elements\":[{\"type\":\"button\",\"text\":{\"type\":\"plain_text\",\"text\":\"Connect To BotApp Tenant\"},\"action_id\":\"connectBotApp\"}]}]}"}
[DEBUG]  web-api:WebClient:1 http request headers: {}
[DEBUG]  web-api:WebClient:1 http response received
(λ: slack) RequestId: cd136606-ca98-4213-bb77-a8c85984775f  Duration: 3832.68 ms  Billed Duration: 3833 ms
[DEBUG]  web-api:WebClient:1 http request result: {"ok":true,"view":{"id":"V070MHSMZ7S","team_id":"T06P3FANVFU","type":"home","blocks":[{"type":"section","block_id":"PyRL2","text":{"type":"mrkdwn","text":"*Welcome to BotApp Bot, <@U06P0HP9Y9K> *","verbatim":false}},{"type":"divider","block_id":"/nSyt"},{"type":"section","block_id":"/JKwZ","text":{"type":"mrkdwn","text":"Your workspace is connected to <https://testtenant.com>. If you wish to change it please connect with your new credentials.","verbatim":false}},{"type":"divider","block_id":"7RCvy"},{"type":"section","block_id":"UdWrM","text":{"type":"mrkdwn","text":"This is BotApp Bot App. As an admin, please configure the BotApp details here. We will integrate that tenant to this slack app.","verbatim":false}},{"type":"actions","block_id":"a87jz","elements":[{"type":"button","action_id":"connectBotApp","text":{"type":"plain_text","text":"Connect To BotApp 
Tenant","emoji":true}}]}],"private_metadata":"","callback_id":"home_view","state":{"values":{}},"hash":"1718184116.ovLp0SIn","title":{"type":"plain_text","text":"View Title","emoji":true},"clear_on_close":false,"notify_on_close":false,"close":null,"submit":null,"previous_view_id":null,"root_view_id":"V070MHSMZ7S","app_id":"A06UFRZN9M5","external_id":"U06P0HP9Y9Kapp_home_block","app_installed_team_id":"T06P3FANVFU","bot_id":"B06UWD4QV6W"},"response_metadata":{"scopes":["calls:write","channels:read","im:history","commands","chat:write","channels:history","users:read.email","users:read"]}}
[DEBUG]  web-api:WebClient:1 apiCall('views.update') end

Not sure what went wrong in here. Modal opens fine when i remove the receiver code. Is it okay if we discuss this here in this issue or should i raise another new issue!?

HarikaKonda01 avatar Jun 12 '24 09:06 HarikaKonda01

On submit, I am opening another modal first and updating that modal with data later. After that, Im updating the app home view.

To open a new modal on top of an existing one in response to an app.view request, you can use views.push instead of views.open API. The views.open call may work occassionally but it is not the right way to manage a few modals for a single interaction. Hope this helps.

seratch avatar Jun 12 '24 09:06 seratch

👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.

github-actions[bot] avatar Jul 15 '24 00:07 github-actions[bot]

As this issue has been inactive for more than one month, we will be closing it. Thank you to all the participants! If you would like to raise a related issue, please create a new issue which includes your specific details and references this issue number.

github-actions[bot] avatar Jul 29 '24 00:07 github-actions[bot]