\(バックスラッシュ)について-添付ファイル付きのGmailメッセージをkintoneに自動的にアップロード

https://cybozudev.zendesk.com/hc/ja/articles/360000744546

上記のサイトを参考に、Gmailの内容をkintoneアプリに連携しています。運用を今年より開始しているのですが、Gmailの件名に\(バックスラッシュ)が付いているものが連携されないことが本日発覚しました。本文にのみ\(バックスラッシュ)があった場合も連携されませんでした。

\(バックスラッシュ)が含まれたメールは、連携が出来ないものなのでしょうか。

 

下記がソースコードです。

/*

* 添付ファイル付のGmailメッセージをkintoneに自動的にアップロード

* Copyright (c) 2018 Cybozu

*

* Licensed under the MIT License

*/

‘use strict’;

var domain = “group.cybozu.com”;

var appId = 581;

var apiToken = “yUmnJbVAsivRgqAuWeihL9ltKzqKNkDJLFhJ5aiy”;

var appName = “ISS(テスト中)”;

function replaceCharacters(str) {

    return str

        .replace(/"/g, “'”)

        .replace(//g, "")

        .replace(/\r/g, “\r”)

        .replace(/\t/g, “\t”);

}

function uploadAttachment(attachment) {

    var blob = attachment.copyBlob();

    // Make a POST request with form data.

    var formData = {

        ‘file’: blob

    };

    var formHeader = {

        ‘X-Requested-With’: ‘XMLHttpRequest’,

        ‘X-Cybozu-API-Token’: apiToken

    };

    // Because payload is a JavaScript object, it will be interpreted as

    // as form data. (No need to specify contentType; it will automatically

    // default to either ‘application/x-www-form-urlencoded’

    // or ‘multipart/form-data’)

    var options = {

        ‘method’: ‘post’,

        ‘headers’: formHeader,

        ‘payload’: formData

    };

    return UrlFetchApp.fetch(‘https://’ + domain + ‘/k/v1/file.json’, options);

}

function getGmailMessage() {

    // Get all unread threads with the subject in inbox

    var threads = GmailApp.search(‘is:unread to:(kanagawa-iss@grp.co.jp)’);

    var records = ‘[’;

    for (var i = 0; i < threads.length; i++) {

        var messages = threads[i].getMessages();// Get messages

        for (var j = 0; j < messages.length; j++) {

            var message = messages[j];

            if(message.isUnread()) { // スレッド内の未読メールのみ対象

                var attachments = message.getAttachments();

                var fileKeys = ‘’;

                for (var k = 0; k < attachments.length; k++) {

                    Logger.log(‘Message “%s” contains the attachment “%s” (%s bytes)’,

                        message.getSubject(), attachments[k].getName(), attachments[k].getSize());

                    var fileKey = uploadAttachment(attachments[k]);

                    if (fileKey !== null) {

                        fileKeys += fileKey + ‘,’;

                    }

                }

                records += Utilities.formatString(‘{“name”: { “value”: “%s” }’,

                    replaceCharacters(message.getFrom()));//送信者の名前の取得

                records += ‘,’ + Utilities.formatString(‘“email” : { “value”: “%s” }’,

                    replaceCharacters(message.getReplyTo()));//送信者のメールアドレス取得

                records += ‘,’ + Utilities.formatString(‘“subject” : { “value”: “%s” }’,

                    replaceCharacters(message.getSubject()));//メール題目の取得

                records += ‘,’ + Utilities.formatString(‘“message” : { “value”: “%s” }’,

                    replaceCharacters(message.getPlainBody()));//メッセージの取得

                if (fileKeys.length > 0) {

                    if (fileKeys.match(‘,$’)) {

                        fileKeys = fileKeys.substring(0, fileKeys.length - 1);

                    }

                    records += ‘,’ + Utilities.formatString(‘“Attachment”:{“value”:[ %s ]}’, fileKeys);//File Keyの設定

                }

                records += ‘},’;

                message.markRead(); // Mark as read

            }

        }

    }

    if (records.match(‘,$’)) {

        records = records.substring(0, records.length - 1);

    }

    records += ‘]’;

    Logger.log(‘Response JSON is “%s”’, records);

    return records;

}

function sendToKintone() {

    Logger.log(‘Function called’);

    var apps = {

        YOUR_APPLICATION1: {

            appid: appId,

            name: appName,

            token: apiToken

        }

    };

    var manager = new KintoneManager.KintoneManager(domain, apps);// ライブラリーの初期化

    var records = JSON.parse(getGmailMessage());// JSON形式に変換

    if (records.length > 0) { //レコードが存在するときのみ生成

        var response = manager.create(“YOUR_APPLICATION1”, records);//kintone レコードの生成

        // ステータスコード

        // 成功すれば200になる

        var code = response.getResponseCode();

        Logger.log(‘Response code is “%s”’, code);

    } else {

        Logger.log(‘No record found’);

    }

}

 

 

例外メッセージなどがあればはっきりするのですが、おそらくgetGmailMessage内でJSON文字列 records を組み立てるときにエスケープ不足になっており JSON.parse() に失敗しているのでしょう。JSON文字列を自前で文字列加工して作るのはこういう落とし穴があるのでやめてほしいところです。とりあえず replaceCharacters関数 において、単独で現れる backslash 1文字 (“\”) を バックスラッシュ2文字 (“\\”) に置換すると回避できるのではないかと思います。

function replaceCharacters(str) {
    return str
        .replace(/"/g, "\'")
        .replace(/\\/g, "\\\\")
        .replace(//g, "\")
        .replace(/\r/g, "\\r")
        .replace(/\t/g, "\\t");
}

この修正でうまくいってもいかなくても、元の記事の末尾で replaceCharacters 関数にバグがある旨フィードバックしてくださるとみんなのためになって嬉しいです

backslash 1文字 (“\”) を バックスラッシュ2文字 (“\\”) に置換したところ、連携されるようになりました!

ありがとうございます!!(フィードバックの件、承知しました。)

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。