1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

GoogleAppsScriptでメンションする

Last updated at Posted at 2022-08-31

やりたいこと

GoogleAppsScriptを使って自分宛へのメンション
スクリーンショット 2022-08-31 19.44.52.png

応用すれば別のユーザーへのメンションにも使えるので、
特定のメールが来たら、特定のユーザーにメンションを飛ばすとかが簡単に実装できます。

コード

@google/claspを使ってローカル環境でTypeScriptで記載します.
型定義は@type/google-apps-scriptを使います
(GASコードも後ろの方で記載します)

メンション用のユーザーIDを取得する

公式リファレンスからGUIでも取得することができます
Method: people.get  |  People API  |  Google Developers

↑のリンクを使えば各項目は記載されていますが、一応スクショも記載
スクリーンショット 2022-08-31 20.12.19.png

GASで取得するとこんな感じ
※マニフェストのスコープを手動で変更する必要があります

oauthScopesの一つ目はPeopleAPIでmetadataを取得するため、
二つ目はURLFetchを使うためです。

appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "People",
        "version": "v1",
        "serviceId": "peopleapi"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

metadata以外のフィールドの取得や、resourceName以外の値については省きます。
↑で記載しているGUIで見た方が早いです

main.ts
/**
 * メンション用のUserIDを取得する
 * @returns {string|undefined} userのIDを取得する
 */
const getUserId = (): string | undefined => {
  if (People.People) {
    const me = People.People?.get("people/me", { personFields: "metadata" });
    const { resourceName } = me;
    if (resourceName) {
      const matchItem = resourceName.match(/^people\/(?<id>[^/]+)$/);
      if (matchItem) {
        const id = matchItem.groups?.id;
        return id;
      } else console.warn(`resourceNameが/^people\/[^/]+$/に一致しませんでした\nresourceName: ${resourceName}`);
    } else console.warn(`resourceNameが取得できませんでした`);
  } else console.warn(`People.Peopleが存在しませんでした`);
  return undefined;
};

メンション用の関数

main.ts
/**
 * UserID宛にメンションする
 * @param {string} userId - メンションするUserID
 * @param {string} botURL - 送信するBOTのWebhookリンク
 */
const notify = (userId: string, botURL: string): void => {
  const message = {
    text: `俺だよ、俺、<users/${userId}>だよ`,
  };
  const param: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions & { method: GoogleAppsScript.URL_Fetch.HttpMethod } = {
    method: `post`,
    headers: {
      "Content-Type": "application/json; charset=UTF-8",
    },
    payload: JSON.stringify(message),
  };
  UrlFetchApp.fetch(botURL, param);
};

実行用のメイン関数

hookURLのところはスペースで作ったWebhookのリンクを使ってくださいね
スクリーンショット 2022-08-31 20.01.23.png

main.ts
/**
 * 実行用の関数
 */
const main = (): void => {
  const hookURL = `https://chat.googleapis.com/v1/spaces/SpaceID/messages?key=BotKeys&token=BotToken`;
  const userId = getUserId();
  if (userId) notify(userId, hookURL);
};

コピペ用

TypeScript

コード
appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "People",
        "version": "v1",
        "serviceId": "peopleapi"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

code.ts
/**
 * 実行用の関数
 */
const main = (): void => {
  const hookURL = `https://chat.googleapis.com/v1/spaces/SpaceID/messages?key=BotKeys&token=BotToken`;
  const userId = getUserId();
  if (userId) notify(userId, hookURL);
};

/**
 * メンション用のUserIDを取得する
 * @returns {string|undefined} userのIDを取得する
 */
const getUserId = (): string | undefined => {
  if (People.People) {
    const me = People.People?.get("people/me", { personFields: "metadata" });
    const { resourceName } = me;
    if (resourceName) {
      const matchItem = resourceName.match(/^people\/(?<id>[^/]+)$/);
      if (matchItem) {
        const id = matchItem.groups?.id;
        return id;
      } else console.warn(`resourceNameが/^people\/[^/]+$/に一致しませんでした\nresourceName: ${resourceName}`);
    } else console.warn(`resourceNameが取得できませんでした`);
  } else console.warn(`People.Peopleが存在しませんでした`);
  return undefined;
};

/**
 * UserID宛にメンションする
 * @param {string} userId - メンションするUserID
 * @param {string} botURL - 送信するBOTのWebhookリンク
 */
const notify = (userId: string, botURL: string): void => {
  const message = {
    text: `俺だよ、俺、<users/${userId}>だよ`,
  };
  const param: GoogleAppsScript.URL_Fetch.URLFetchRequestOptions & { method: GoogleAppsScript.URL_Fetch.HttpMethod } = {
    method: `post`,
    headers: {
      "Content-Type": "application/json; charset=UTF-8",
    },
    payload: JSON.stringify(message),
  };
  UrlFetchApp.fetch(botURL, param);
};

GAS

コード
appsscript.json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "People",
        "version": "v1",
        "serviceId": "peopleapi"
      }
    ]
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/userinfo.profile",
    "https://www.googleapis.com/auth/script.external_request"
  ]
}

code.gs
/**
 * 実行用の関数
 */
const main = () => {
  const hookURL = `https://chat.googleapis.com/v1/spaces/SpaceID/messages?key=BotKeys&token=BotToken`;
  const userId = getUserId();
  if (userId) notify(userId, hookURL);
};

/**
 * メンション用のUserIDを取得する
 * @returns {string|undefined} userのIDを取得する
 */
const getUserId = () => {
  if (People.People) {
    const me = People.People?.get("people/me", { personFields: "metadata" });
    const { resourceName } = me;
    if (resourceName) {
      const matchItem = resourceName.match(/^people\/(?<id>[^/]+)$/);
      if (matchItem) {
        const id = matchItem.groups?.id;
        return id;
      } else console.warn(`resourceNameが/^people\/[^/]+$/に一致しませんでした\nresourceName: ${resourceName}`);
    } else console.warn(`resourceNameが取得できませんでした`);
  } else console.warn(`People.Peopleが存在しませんでした`);
  return undefined;
};

/**
 * UserID宛にメンションする
 * @param {string} userId - メンションするUserID
 * @param {string} botURL - 送信するBOTのWebhookリンク
 */
const notify = (userId, botURL) => {
  const message = {
    text: `俺だよ、俺、<users/${userId}>だよ`,
  };
  const param = {
    method: `post`,
    headers: {
      "Content-Type": "application/json; charset=UTF-8",
    },
    payload: JSON.stringify(message),
  };
  UrlFetchApp.fetch(botURL, param);
};

結果

mainを実行して、スコープを認証すれば通知が行われます。
スクリーンショット 2022-08-31 19.44.52.png

他ユーザーへのメンション

自分以外のUserIDについては管理者ロールを持っていれば取得できそうですが、
私は持っていないため、取得方法は不明。
なので、一般権限のユーザーが、他のユーザーへのメンションを作成する場合は、
前もってメンションするユーザーにIDを取得しておいてもらう必要があるので注意が必要です。
(私の場合は、各自にWebAppにアクセスしてもらい、裏でIDを取得してスプレッドシートに記載されるような仕組みにしました)

試していませんがAdmin SDK APIでも取得できるらしいです
こっちだとメールアドレスで取得できるからこっちの方でしょう、絶対!
Google Chat botがメンションするのに必要なUser IDを開発者コンソールに出力するスクリプト - Qiita

まとめ

ということでお手軽にメンションすることができましたね。
metadataを取得するために、oauthScopesを自分で記載する必要があることがミソでしょうか。
普段は自動でスコープを与えてくれている分、
いざFetchを使ったり、SpreadSheetを使うと「権限が足りん!」って怒られちゃうので、
その辺は割と面倒だったり。。。
とはいえ、PeopleAPIなんかは特に適当にロール付与しまくるのは怖いので、
ロール管理は学んでおいた方がいいのかもしれない。。。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?